changeset 48215:5ee29f4ec472

Merge
author jwilhelm
date Sat, 02 Dec 2017 06:51:10 +0100
parents f5d7096cfdc0 255407049d98
children afcefb8ab1e1
files src/hotspot/cpu/aarch64/vm_version_aarch64.cpp src/hotspot/share/classfile/vmSymbols_ext.hpp src/hotspot/share/gc/g1/g1MemoryPool.cpp src/hotspot/share/gc/g1/g1MemoryPool.hpp src/hotspot/share/gc/g1/hSpaceCounters.cpp src/hotspot/share/gc/g1/hSpaceCounters.hpp src/hotspot/share/gc/parallel/psMemoryPool.cpp src/hotspot/share/gc/parallel/psMemoryPool.hpp src/hotspot/share/gc/shared/hSpaceCounters.cpp src/hotspot/share/gc/shared/hSpaceCounters.hpp src/hotspot/share/prims/jvm.cpp src/hotspot/share/services/g1MemoryPool.cpp src/hotspot/share/services/g1MemoryPool.hpp src/hotspot/share/services/jmm.h src/hotspot/share/services/psMemoryPool.cpp src/hotspot/share/services/psMemoryPool.hpp src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/MachineDescriptionIA64.java src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/ia64/IA64ThreadContext.java src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/linux/ia64/LinuxIA64ThreadContext.java src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/windbg/ia64/WindbgIA64Thread.java src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/windbg/ia64/WindbgIA64ThreadContext.java src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/windbg/ia64/WindbgIA64ThreadFactory.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/address/RawAddressNode.java src/utils/LogCompilation/src/com/sun/hotspot/tools/compiler/BasicLogEvent.java src/utils/LogCompilation/src/com/sun/hotspot/tools/compiler/CallSite.java src/utils/LogCompilation/src/com/sun/hotspot/tools/compiler/Compilation.java src/utils/LogCompilation/src/com/sun/hotspot/tools/compiler/Constants.java src/utils/LogCompilation/src/com/sun/hotspot/tools/compiler/LogCleanupReader.java src/utils/LogCompilation/src/com/sun/hotspot/tools/compiler/LogCompilation.java src/utils/LogCompilation/src/com/sun/hotspot/tools/compiler/LogEvent.java src/utils/LogCompilation/src/com/sun/hotspot/tools/compiler/LogParser.java src/utils/LogCompilation/src/com/sun/hotspot/tools/compiler/MakeNotEntrantEvent.java src/utils/LogCompilation/src/com/sun/hotspot/tools/compiler/Method.java src/utils/LogCompilation/src/com/sun/hotspot/tools/compiler/NMethod.java src/utils/LogCompilation/src/com/sun/hotspot/tools/compiler/Phase.java src/utils/LogCompilation/src/com/sun/hotspot/tools/compiler/UncommonTrap.java src/utils/LogCompilation/src/com/sun/hotspot/tools/compiler/UncommonTrapEvent.java test/hotspot/jtreg/gc/metaspace/PerfCounter.java test/hotspot/jtreg/gc/metaspace/PerfCounters.java
diffstat 934 files changed, 53318 insertions(+), 10800 deletions(-) [+]
line wrap: on
line diff
--- a/make/hotspot/lib/CompileJvm.gmk	Wed Dec 06 15:14:13 2017 -0800
+++ b/make/hotspot/lib/CompileJvm.gmk	Sat Dec 02 06:51:10 2017 +0100
@@ -59,6 +59,7 @@
     -I$(TOPDIR)/src/hotspot/share/precompiled \
     -I$(TOPDIR)/src/java.base/share/native/include \
     -I$(TOPDIR)/src/java.base/$(OPENJDK_TARGET_OS_TYPE)/native/include \
+    -I$(TOPDIR)/src/java.management/share/native/include \
     -I$(TOPDIR)/src/java.base/share/native/libjimage \
     #
 
--- a/make/test/JtregNativeHotspot.gmk	Wed Dec 06 15:14:13 2017 -0800
+++ b/make/test/JtregNativeHotspot.gmk	Sat Dec 02 06:51:10 2017 +0100
@@ -79,6 +79,7 @@
     $(TOPDIR)/test/hotspot/jtreg/serviceability/jvmti/ModuleAwareAgents/ClassLoadPrepare \
     $(TOPDIR)/test/hotspot/jtreg/serviceability/jvmti/ModuleAwareAgents/ThreadStart \
     $(TOPDIR)/test/hotspot/jtreg/serviceability/jvmti/StartPhase/AllowedFunctions \
+    $(TOPDIR)/test/hotspot/jtreg/serviceability/dcmd/jvmti/AttachFailed \
     #
 
 # Add conditional directories here when needed.
@@ -110,6 +111,8 @@
     BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libAllowedFunctions := -lc
     BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libRedefineDoubleDelete := -lc
     BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libHandshakeTransitionTest := -lc
+    BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libHasNoEntryPoint := -lc
+    BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libReturnError := -lc
 endif
 
 ifeq ($(OPENJDK_TARGET_OS), linux)
--- a/src/hotspot/cpu/aarch64/assembler_aarch64.hpp	Wed Dec 06 15:14:13 2017 -0800
+++ b/src/hotspot/cpu/aarch64/assembler_aarch64.hpp	Sat Dec 02 06:51:10 2017 +0100
@@ -985,12 +985,33 @@
   }
 
   void hint(int imm) {
-    system(0b00, 0b011, 0b0010, imm, 0b000);
+    system(0b00, 0b011, 0b0010, 0b0000, imm);
   }
 
   void nop() {
     hint(0);
   }
+
+  void yield() {
+    hint(1);
+  }
+
+  void wfe() {
+    hint(2);
+  }
+
+  void wfi() {
+    hint(3);
+  }
+
+  void sev() {
+    hint(4);
+  }
+
+  void sevl() {
+    hint(5);
+  }
+
   // we only provide mrs and msr for the special purpose system
   // registers where op1 (instr[20:19]) == 11 and, (currently) only
   // use it for FPSR n.b msr has L (instr[21]) == 0 mrs has L == 1
--- a/src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp	Wed Dec 06 15:14:13 2017 -0800
+++ b/src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp	Sat Dec 02 06:51:10 2017 +0100
@@ -494,42 +494,6 @@
   }
 }
 
-// Rather than take a segfault when the polling page is protected,
-// explicitly check for a safepoint in progress and if there is one,
-// fake a call to the handler as if a segfault had been caught.
-void LIR_Assembler::poll_for_safepoint(relocInfo::relocType rtype, CodeEmitInfo* info) {
-  __ mov(rscratch1, SafepointSynchronize::address_of_state());
-  __ ldrb(rscratch1, Address(rscratch1));
-  Label nope, poll;
-  __ cbz(rscratch1, nope);
-  __ block_comment("safepoint");
-  __ enter();
-  __ push(0x3, sp);                // r0 & r1
-  __ push(0x3ffffffc, sp);         // integer registers except lr & sp & r0 & r1
-  __ adr(r0, poll);
-  __ str(r0, Address(rthread, JavaThread::saved_exception_pc_offset()));
-  __ mov(rscratch1, CAST_FROM_FN_PTR(address, SharedRuntime::get_poll_stub));
-  __ blrt(rscratch1, 1, 0, 1);
-  __ maybe_isb();
-  __ pop(0x3ffffffc, sp);          // integer registers except lr & sp & r0 & r1
-  __ mov(rscratch1, r0);
-  __ pop(0x3, sp);                 // r0 & r1
-  __ leave();
-  __ br(rscratch1);
-  address polling_page(os::get_polling_page());
-  assert(os::is_poll_address(polling_page), "should be");
-  unsigned long off;
-  __ adrp(rscratch1, Address(polling_page, rtype), off);
-  __ bind(poll);
-  if (info)
-    add_debug_info_for_branch(info);  // This isn't just debug info:
-                                      // it's the oop map
-  else
-    __ code_section()->relocate(pc(), rtype);
-  __ ldrw(zr, Address(rscratch1, off));
-  __ bind(nope);
-}
-
 void LIR_Assembler::return_op(LIR_Opr result) {
   assert(result->is_illegal() || !result->is_single_cpu() || result->as_register() == r0, "word returns are in r0,");
 
@@ -549,11 +513,9 @@
   address polling_page(os::get_polling_page());
   guarantee(info != NULL, "Shouldn't be NULL");
   assert(os::is_poll_address(polling_page), "should be");
-  unsigned long off;
-  __ adrp(rscratch1, Address(polling_page, relocInfo::poll_type), off);
-  assert(off == 0, "must be");
+  __ get_polling_page(rscratch1, polling_page, relocInfo::poll_type);
   add_debug_info_for_branch(info);  // This isn't just debug info:
-  // it's the oop map
+                                    // it's the oop map
   __ read_polling_page(rscratch1, relocInfo::poll_type);
   return __ offset();
 }
--- a/src/hotspot/cpu/aarch64/globalDefinitions_aarch64.hpp	Wed Dec 06 15:14:13 2017 -0800
+++ b/src/hotspot/cpu/aarch64/globalDefinitions_aarch64.hpp	Sat Dec 02 06:51:10 2017 +0100
@@ -51,4 +51,6 @@
 
 #define SUPPORT_RESERVED_STACK_AREA
 
+#define THREAD_LOCAL_POLL
+
 #endif // CPU_AARCH64_VM_GLOBALDEFINITIONS_AARCH64_HPP
--- a/src/hotspot/cpu/aarch64/globals_aarch64.hpp	Wed Dec 06 15:14:13 2017 -0800
+++ b/src/hotspot/cpu/aarch64/globals_aarch64.hpp	Sat Dec 02 06:51:10 2017 +0100
@@ -79,7 +79,7 @@
 // Clear short arrays bigger than one word in an arch-specific way
 define_pd_global(intx, InitArrayShortSize, BytesPerLong);
 
-define_pd_global(bool, ThreadLocalHandshakes, false);
+define_pd_global(bool, ThreadLocalHandshakes, true);
 
 #if defined(COMPILER1) || defined(COMPILER2)
 define_pd_global(intx, InlineSmallCode,          1000);
--- a/src/hotspot/cpu/aarch64/interp_masm_aarch64.cpp	Wed Dec 06 15:14:13 2017 -0800
+++ b/src/hotspot/cpu/aarch64/interp_masm_aarch64.cpp	Sat Dec 02 06:51:10 2017 +0100
@@ -30,12 +30,13 @@
 #include "logging/log.hpp"
 #include "oops/arrayOop.hpp"
 #include "oops/markOop.hpp"
+#include "oops/method.hpp"
 #include "oops/methodData.hpp"
-#include "oops/method.hpp"
 #include "prims/jvmtiExport.hpp"
 #include "prims/jvmtiThreadState.hpp"
 #include "runtime/basicLock.hpp"
 #include "runtime/biasedLocking.hpp"
+#include "runtime/safepointMechanism.hpp"
 #include "runtime/sharedRuntime.hpp"
 #include "runtime/thread.inline.hpp"
 
@@ -438,13 +439,26 @@
 
 void InterpreterMacroAssembler::dispatch_base(TosState state,
                                               address* table,
-                                              bool verifyoop) {
+                                              bool verifyoop,
+                                              bool generate_poll) {
   if (VerifyActivationFrameSize) {
     Unimplemented();
   }
   if (verifyoop) {
     verify_oop(r0, state);
   }
+
+  Label safepoint;
+  address* const safepoint_table = Interpreter::safept_table(state);
+  bool needs_thread_local_poll = generate_poll &&
+    SafepointMechanism::uses_thread_local_poll() && table != safepoint_table;
+
+  if (needs_thread_local_poll) {
+    NOT_PRODUCT(block_comment("Thread-local Safepoint poll"));
+    ldr(rscratch2, Address(rthread, Thread::polling_page_offset()));
+    tbnz(rscratch2, exact_log2(SafepointMechanism::poll_bit()), safepoint);
+  }
+
   if (table == Interpreter::dispatch_table(state)) {
     addw(rscratch2, rscratch1, Interpreter::distance_from_dispatch_table(state));
     ldr(rscratch2, Address(rdispatch, rscratch2, Address::uxtw(3)));
@@ -453,10 +467,17 @@
     ldr(rscratch2, Address(rscratch2, rscratch1, Address::uxtw(3)));
   }
   br(rscratch2);
+
+  if (needs_thread_local_poll) {
+    bind(safepoint);
+    lea(rscratch2, ExternalAddress((address)safepoint_table));
+    ldr(rscratch2, Address(rscratch2, rscratch1, Address::uxtw(3)));
+    br(rscratch2);
+  }
 }
 
-void InterpreterMacroAssembler::dispatch_only(TosState state) {
-  dispatch_base(state, Interpreter::dispatch_table(state));
+void InterpreterMacroAssembler::dispatch_only(TosState state, bool generate_poll) {
+  dispatch_base(state, Interpreter::dispatch_table(state), true, generate_poll);
 }
 
 void InterpreterMacroAssembler::dispatch_only_normal(TosState state) {
@@ -468,10 +489,10 @@
 }
 
 
-void InterpreterMacroAssembler::dispatch_next(TosState state, int step) {
+void InterpreterMacroAssembler::dispatch_next(TosState state, int step, bool generate_poll) {
   // load next bytecode
   ldrb(rscratch1, Address(pre(rbcp, step)));
-  dispatch_base(state, Interpreter::dispatch_table(state));
+  dispatch_base(state, Interpreter::dispatch_table(state), generate_poll);
 }
 
 void InterpreterMacroAssembler::dispatch_via(TosState state, address* table) {
@@ -1585,6 +1606,7 @@
 }
 
 void InterpreterMacroAssembler::profile_obj_type(Register obj, const Address& mdo_addr) {
+  assert_different_registers(obj, rscratch1);
   Label update, next, none;
 
   verify_oop(obj);
@@ -1745,6 +1767,7 @@
 }
 
 void InterpreterMacroAssembler::profile_parameters_type(Register mdp, Register tmp1, Register tmp2) {
+  assert_different_registers(rscratch1, rscratch2, mdp, tmp1, tmp2);
   if (ProfileInterpreter && MethodData::profile_parameters()) {
     Label profile_continue, done;
 
@@ -1752,8 +1775,8 @@
 
     // Load the offset of the area within the MDO used for
     // parameters. If it's negative we're not profiling any parameters
-    ldr(tmp1, Address(mdp, in_bytes(MethodData::parameters_type_data_di_offset()) - in_bytes(MethodData::data_offset())));
-    tbnz(tmp1, 63, profile_continue);  // i.e. sign bit set
+    ldrw(tmp1, Address(mdp, in_bytes(MethodData::parameters_type_data_di_offset()) - in_bytes(MethodData::data_offset())));
+    tbnz(tmp1, 31, profile_continue);  // i.e. sign bit set
 
     // Compute a pointer to the area for parameters from the offset
     // and move the pointer to the slot for the last
--- a/src/hotspot/cpu/aarch64/interp_masm_aarch64.hpp	Wed Dec 06 15:14:13 2017 -0800
+++ b/src/hotspot/cpu/aarch64/interp_masm_aarch64.hpp	Sat Dec 02 06:51:10 2017 +0100
@@ -55,7 +55,8 @@
                             bool check_exceptions);
 
   // base routine for all dispatches
-  void dispatch_base(TosState state, address* table, bool verifyoop = true);
+  void dispatch_base(TosState state, address* table,
+                     bool verifyoop = true, bool generate_poll = false);
 
  public:
   InterpreterMacroAssembler(CodeBuffer* code) : MacroAssembler(code) {}
@@ -165,12 +166,12 @@
   void dispatch_prolog(TosState state, int step = 0);
   void dispatch_epilog(TosState state, int step = 0);
   // dispatch via rscratch1
-  void dispatch_only(TosState state);
+  void dispatch_only(TosState state, bool generate_poll = false);
   // dispatch normal table via rscratch1 (assume rscratch1 is loaded already)
   void dispatch_only_normal(TosState state);
   void dispatch_only_noverify(TosState state);
   // load rscratch1 from [rbcp + step] and dispatch via rscratch1
-  void dispatch_next(TosState state, int step = 0);
+  void dispatch_next(TosState state, int step = 0, bool generate_poll = false);
   // load rscratch1 from [esi] and dispatch via rscratch1 and table
   void dispatch_via (TosState state, address* table);
 
--- a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp	Wed Dec 06 15:14:13 2017 -0800
+++ b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp	Sat Dec 02 06:51:10 2017 +0100
@@ -287,6 +287,40 @@
   dsb(Assembler::SY);
 }
 
+void MacroAssembler::safepoint_poll(Label& slow_path) {
+  if (SafepointMechanism::uses_thread_local_poll()) {
+    ldr(rscratch1, Address(rthread, Thread::polling_page_offset()));
+    tbnz(rscratch1, exact_log2(SafepointMechanism::poll_bit()), slow_path);
+  } else {
+    unsigned long offset;
+    adrp(rscratch1, ExternalAddress(SafepointSynchronize::address_of_state()), offset);
+    ldrw(rscratch1, Address(rscratch1, offset));
+    assert(SafepointSynchronize::_not_synchronized == 0, "rewrite this code");
+    cbnz(rscratch1, slow_path);
+  }
+}
+
+// Just like safepoint_poll, but use an acquiring load for thread-
+// local polling.
+//
+// We need an acquire here to ensure that any subsequent load of the
+// global SafepointSynchronize::_state flag is ordered after this load
+// of the local Thread::_polling page.  We don't want this poll to
+// return false (i.e. not safepointing) and a later poll of the global
+// SafepointSynchronize::_state spuriously to return true.
+//
+// This is to avoid a race when we're in a native->Java transition
+// racing the code which wakes up from a safepoint.
+//
+void MacroAssembler::safepoint_poll_acquire(Label& slow_path) {
+  if (SafepointMechanism::uses_thread_local_poll()) {
+    lea(rscratch1, Address(rthread, Thread::polling_page_offset()));
+    ldar(rscratch1, rscratch1);
+    tbnz(rscratch1, exact_log2(SafepointMechanism::poll_bit()), slow_path);
+  } else {
+    safepoint_poll(slow_path);
+  }
+}
 
 void MacroAssembler::reset_last_Java_frame(bool clear_fp) {
   // we must set sp to zero to clear frame
@@ -4336,15 +4370,26 @@
 }
 
 
+// Move the address of the polling page into dest.
+void MacroAssembler::get_polling_page(Register dest, address page, relocInfo::relocType rtype) {
+  if (SafepointMechanism::uses_thread_local_poll()) {
+    ldr(dest, Address(rthread, Thread::polling_page_offset()));
+  } else {
+    unsigned long off;
+    adrp(dest, Address(page, rtype), off);
+    assert(off == 0, "polling page must be page aligned");
+  }
+}
+
+// Move the address of the polling page into r, then read the polling
+// page.
 address MacroAssembler::read_polling_page(Register r, address page, relocInfo::relocType rtype) {
-  unsigned long off;
-  adrp(r, Address(page, rtype), off);
-  InstructionMark im(this);
-  code_section()->relocate(inst_mark(), rtype);
-  ldrw(zr, Address(r, off));
-  return inst_mark();
-}
-
+  get_polling_page(r, page, rtype);
+  return read_polling_page(r, rtype);
+}
+
+// Read the polling page.  The address of the polling page must
+// already be in r.
 address MacroAssembler::read_polling_page(Register r, relocInfo::relocType rtype) {
   InstructionMark im(this);
   code_section()->relocate(inst_mark(), rtype);
--- a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp	Wed Dec 06 15:14:13 2017 -0800
+++ b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp	Sat Dec 02 06:51:10 2017 +0100
@@ -97,6 +97,9 @@
  virtual void check_and_handle_popframe(Register java_thread);
  virtual void check_and_handle_earlyret(Register java_thread);
 
+  void safepoint_poll(Label& slow_path);
+  void safepoint_poll_acquire(Label& slow_path);
+
   // Biased locking support
   // lock_reg and obj_reg must be loaded up with the appropriate values.
   // swap_reg is killed.
@@ -995,12 +998,12 @@
   void atomic_xchgalw(Register prev, Register newv, Register addr);
 
   void orptr(Address adr, RegisterOrConstant src) {
-    ldr(rscratch2, adr);
+    ldr(rscratch1, adr);
     if (src.is_register())
-      orr(rscratch2, rscratch2, src.as_register());
+      orr(rscratch1, rscratch1, src.as_register());
     else
-      orr(rscratch2, rscratch2, src.as_constant());
-    str(rscratch2, adr);
+      orr(rscratch1, rscratch1, src.as_constant());
+    str(rscratch1, adr);
   }
 
   // A generic CAS; success or failure is in the EQ flag.
@@ -1199,6 +1202,7 @@
 
   address read_polling_page(Register r, address page, relocInfo::relocType rtype);
   address read_polling_page(Register r, relocInfo::relocType rtype);
+  void get_polling_page(Register dest, address page, relocInfo::relocType rtype);
 
   // CRC32 code for java.util.zip.CRC32::updateBytes() instrinsic.
   void update_byte_crc32(Register crc, Register val, Register table);
--- a/src/hotspot/cpu/aarch64/nativeInst_aarch64.cpp	Wed Dec 06 15:14:13 2017 -0800
+++ b/src/hotspot/cpu/aarch64/nativeInst_aarch64.cpp	Sat Dec 02 06:51:10 2017 +0100
@@ -245,6 +245,11 @@
   // mov(reg, polling_page);
   // ldr(zr, [reg, #offset]);
   //
+  // or
+  //
+  // ldr(reg, [rthread, #offset]);
+  // ldr(zr, [reg, #offset]);
+  //
   // however, we cannot rely on the polling page address load always
   // directly preceding the read from the page. C1 does that but C2
   // has to do the load and read as two independent instruction
--- a/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp	Wed Dec 06 15:14:13 2017 -0800
+++ b/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp	Sat Dec 02 06:51:10 2017 +0100
@@ -1664,7 +1664,7 @@
   // critical natives they are offset down.
   GrowableArray<int> arg_order(2 * total_in_args);
   VMRegPair tmp_vmreg;
-  tmp_vmreg.set1(r19->as_VMReg());
+  tmp_vmreg.set2(r19->as_VMReg());
 
   if (!is_critical_native) {
     for (int i = total_in_args - 1, c_arg = total_c_args - 1; i >= 0; i--, c_arg--) {
@@ -1952,7 +1952,7 @@
       __ strw(rscratch1, Address(rthread, JavaThread::thread_state_offset()));
 
       // Force this write out before the read below
-      __ dmb(Assembler::SY);
+      __ dmb(Assembler::ISH);
     } else {
       __ lea(rscratch2, Address(rthread, JavaThread::thread_state_offset()));
       __ stlrw(rscratch1, rscratch2);
@@ -1970,13 +1970,7 @@
   // check for safepoint operation in progress and/or pending suspend requests
   Label safepoint_in_progress, safepoint_in_progress_done;
   {
-    assert(SafepointSynchronize::_not_synchronized == 0, "fix this code");
-    unsigned long offset;
-    __ adrp(rscratch1,
-            ExternalAddress((address)SafepointSynchronize::address_of_state()),
-            offset);
-    __ ldrw(rscratch1, Address(rscratch1, offset));
-    __ cbnzw(rscratch1, safepoint_in_progress);
+    __ safepoint_poll_acquire(safepoint_in_progress);
     __ ldrw(rscratch1, Address(rthread, JavaThread::suspend_flags_offset()));
     __ cbnzw(rscratch1, safepoint_in_progress);
     __ bind(safepoint_in_progress_done);
@@ -2932,8 +2926,11 @@
 
   if (!cause_return) {
     // overwrite the return address pushed by save_live_registers
-    __ ldr(c_rarg0, Address(rthread, JavaThread::saved_exception_pc_offset()));
-    __ str(c_rarg0, Address(rfp, wordSize));
+    // Additionally, r20 is a callee-saved register so we can look at
+    // it later to determine if someone changed the return address for
+    // us!
+    __ ldr(r20, Address(rthread, JavaThread::saved_exception_pc_offset()));
+    __ str(r20, Address(rfp, wordSize));
   }
 
   // Do the call
@@ -2968,11 +2965,40 @@
   // No exception case
   __ bind(noException);
 
+  Label no_adjust, bail;
+  if (SafepointMechanism::uses_thread_local_poll() && !cause_return) {
+    // If our stashed return pc was modified by the runtime we avoid touching it
+    __ ldr(rscratch1, Address(rfp, wordSize));
+    __ cmp(r20, rscratch1);
+    __ br(Assembler::NE, no_adjust);
+
+#ifdef ASSERT
+    // Verify the correct encoding of the poll we're about to skip.
+    // See NativeInstruction::is_ldrw_to_zr()
+    __ ldrw(rscratch1, Address(r20));
+    __ ubfx(rscratch2, rscratch1, 22, 10);
+    __ cmpw(rscratch2, 0b1011100101);
+    __ br(Assembler::NE, bail);
+    __ ubfx(rscratch2, rscratch1, 0, 5);
+    __ cmpw(rscratch2, 0b11111);
+    __ br(Assembler::NE, bail);
+#endif
+    // Adjust return pc forward to step over the safepoint poll instruction
+    __ add(r20, r20, NativeInstruction::instruction_size);
+    __ str(r20, Address(rfp, wordSize));
+  }
+
+  __ bind(no_adjust);
   // Normal exit, restore registers and exit.
   RegisterSaver::restore_live_registers(masm, save_vectors);
 
   __ ret(lr);
 
+#ifdef ASSERT
+  __ bind(bail);
+  __ stop("Attempting to adjust pc to skip safepoint poll but the return point is not what we expected");
+#endif
+
   // Make sure all code is generated
   masm->flush();
 
--- a/src/hotspot/cpu/aarch64/templateInterpreterGenerator_aarch64.cpp	Wed Dec 06 15:14:13 2017 -0800
+++ b/src/hotspot/cpu/aarch64/templateInterpreterGenerator_aarch64.cpp	Sat Dec 02 06:51:10 2017 +0100
@@ -414,6 +414,14 @@
   __ restore_constant_pool_cache();
   __ get_method(rmethod);
 
+  if (state == atos) {
+    Register obj = r0;
+    Register mdp = r1;
+    Register tmp = r2;
+    __ ldr(mdp, Address(rmethod, Method::method_data_offset()));
+    __ profile_return_type(mdp, obj, tmp);
+  }
+
   // Pop N words from the stack
   __ get_cache_and_index_at_bcp(r1, r2, 1, index_size);
   __ ldr(r1, Address(r1, ConstantPoolCache::base_offset() + ConstantPoolCacheEntry::flags_offset()));
@@ -967,12 +975,7 @@
 
     Label slow_path;
     // If we need a safepoint check, generate full interpreter entry.
-    ExternalAddress state(SafepointSynchronize::address_of_state());
-    unsigned long offset;
-    __ adrp(rscratch1, ExternalAddress(SafepointSynchronize::address_of_state()), offset);
-    __ ldrw(rscratch1, Address(rscratch1, offset));
-    assert(SafepointSynchronize::_not_synchronized == 0, "rewrite this code");
-    __ cbnz(rscratch1, slow_path);
+    __ safepoint_poll(slow_path);
 
     // We don't generate local frame and don't align stack because
     // we call stub code and there is no safepoint on this path.
@@ -986,6 +989,7 @@
     __ ldrw(val, Address(esp, 0));              // byte value
     __ ldrw(crc, Address(esp, wordSize));       // Initial CRC
 
+    unsigned long offset;
     __ adrp(tbl, ExternalAddress(StubRoutines::crc_table_addr()), offset);
     __ add(tbl, tbl, offset);
 
@@ -1020,12 +1024,7 @@
 
     Label slow_path;
     // If we need a safepoint check, generate full interpreter entry.
-    ExternalAddress state(SafepointSynchronize::address_of_state());
-    unsigned long offset;
-    __ adrp(rscratch1, ExternalAddress(SafepointSynchronize::address_of_state()), offset);
-    __ ldrw(rscratch1, Address(rscratch1, offset));
-    assert(SafepointSynchronize::_not_synchronized == 0, "rewrite this code");
-    __ cbnz(rscratch1, slow_path);
+    __ safepoint_poll(slow_path);
 
     // We don't generate local frame and don't align stack because
     // we call stub code and there is no safepoint on this path.
@@ -1375,7 +1374,7 @@
   if (os::is_MP()) {
     if (UseMembar) {
       // Force this write out before the read below
-      __ dsb(Assembler::SY);
+      __ dmb(Assembler::ISH);
     } else {
       // Write serialization page so VM thread can do a pseudo remote membar.
       // We use the current thread pointer to calculate a thread specific
@@ -1387,16 +1386,8 @@
 
   // check for safepoint operation in progress and/or pending suspend requests
   {
-    Label Continue;
-    {
-      unsigned long offset;
-      __ adrp(rscratch2, SafepointSynchronize::address_of_state(), offset);
-      __ ldrw(rscratch2, Address(rscratch2, offset));
-    }
-    assert(SafepointSynchronize::_not_synchronized == 0,
-           "SafepointSynchronize::_not_synchronized");
-    Label L;
-    __ cbnz(rscratch2, L);
+    Label L, Continue;
+    __ safepoint_poll_acquire(L);
     __ ldrw(rscratch2, Address(rthread, JavaThread::suspend_flags_offset()));
     __ cbz(rscratch2, Continue);
     __ bind(L);
@@ -1671,6 +1662,14 @@
   __ mov(rscratch2, true);
   __ strb(rscratch2, do_not_unlock_if_synchronized);
 
+  Label no_mdp;
+  Register mdp = r3;
+  __ ldr(mdp, Address(rmethod, Method::method_data_offset()));
+  __ cbz(mdp, no_mdp);
+  __ add(mdp, mdp, in_bytes(MethodData::data_offset()));
+  __ profile_parameters_type(mdp, r1, r2);
+  __ bind(no_mdp);
+
   // increment invocation count & check for overflow
   Label invocation_counter_overflow;
   Label profile_method;
--- a/src/hotspot/cpu/aarch64/templateTable_aarch64.cpp	Wed Dec 06 15:14:13 2017 -0800
+++ b/src/hotspot/cpu/aarch64/templateTable_aarch64.cpp	Sat Dec 02 06:51:10 2017 +0100
@@ -1717,7 +1717,7 @@
     __ push_i(r1);
     // Adjust the bcp by the 16-bit displacement in r2
     __ add(rbcp, rbcp, r2);
-    __ dispatch_only(vtos);
+    __ dispatch_only(vtos, /*generate_poll*/true);
     return;
   }
 
@@ -1833,7 +1833,7 @@
   // continue with the bytecode @ target
   // rscratch1: target bytecode
   // rbcp: target bcp
-  __ dispatch_only(vtos);
+  __ dispatch_only(vtos, /*generate_poll*/true);
 
   if (UseLoopCounter) {
     if (ProfileInterpreter) {
@@ -1973,7 +1973,7 @@
   __ ldr(rbcp, Address(rmethod, Method::const_offset()));
   __ lea(rbcp, Address(rbcp, r1));
   __ add(rbcp, rbcp, in_bytes(ConstMethod::codes_offset()));
-  __ dispatch_next(vtos);
+  __ dispatch_next(vtos, 0, /*generate_poll*/true);
 }
 
 void TemplateTable::wide_ret() {
@@ -1984,7 +1984,7 @@
   __ ldr(rbcp, Address(rmethod, Method::const_offset()));
   __ lea(rbcp, Address(rbcp, r1));
   __ add(rbcp, rbcp, in_bytes(ConstMethod::codes_offset()));
-  __ dispatch_next(vtos);
+  __ dispatch_next(vtos, 0, /*generate_poll*/true);
 }
 
 
@@ -2014,7 +2014,7 @@
   __ rev32(r3, r3);
   __ load_unsigned_byte(rscratch1, Address(rbcp, r3, Address::sxtw(0)));
   __ add(rbcp, rbcp, r3, ext::sxtw);
-  __ dispatch_only(vtos);
+  __ dispatch_only(vtos, /*generate_poll*/true);
   // handle default
   __ bind(default_case);
   __ profile_switch_default(r0);
@@ -2064,7 +2064,7 @@
   __ rev32(r3, r3);
   __ add(rbcp, rbcp, r3, ext::sxtw);
   __ ldrb(rscratch1, Address(rbcp, 0));
-  __ dispatch_only(vtos);
+  __ dispatch_only(vtos, /*generate_poll*/true);
 }
 
 void TemplateTable::fast_binaryswitch() {
@@ -2162,7 +2162,7 @@
   __ rev32(j, j);
   __ load_unsigned_byte(rscratch1, Address(rbcp, j, Address::sxtw(0)));
   __ lea(rbcp, Address(rbcp, j, Address::sxtw(0)));
-  __ dispatch_only(vtos);
+  __ dispatch_only(vtos, /*generate_poll*/true);
 
   // default case -> j = default offset
   __ bind(default_case);
@@ -2171,7 +2171,7 @@
   __ rev32(j, j);
   __ load_unsigned_byte(rscratch1, Address(rbcp, j, Address::sxtw(0)));
   __ lea(rbcp, Address(rbcp, j, Address::sxtw(0)));
-  __ dispatch_only(vtos);
+  __ dispatch_only(vtos, /*generate_poll*/true);
 }
 
 
--- a/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp	Wed Dec 06 15:14:13 2017 -0800
+++ b/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp	Sat Dec 02 06:51:10 2017 +0100
@@ -394,4 +394,6 @@
                                    g.generate_getPsrInfo());
 
   get_processor_features();
+
+  UNSUPPORTED_OPTION(CriticalJNINatives);
 }
--- a/src/hotspot/cpu/arm/stubGenerator_arm.cpp	Wed Dec 06 15:14:13 2017 -0800
+++ b/src/hotspot/cpu/arm/stubGenerator_arm.cpp	Sat Dec 02 06:51:10 2017 +0100
@@ -2968,7 +2968,9 @@
         CardTableModRefBS* ct = barrier_set_cast<CardTableModRefBS>(bs);
         assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code");
 
-        Label L_cardtable_loop;
+        Label L_cardtable_loop, L_done;
+
+        __ cbz_32(count, L_done); // zero count - nothing to do
 
         __ add_ptr_scaled_int32(count, addr, count, LogBytesPerHeapOop);
         __ sub(count, count, BytesPerHeapOop);                            // last addr
@@ -2987,6 +2989,7 @@
         __ strb(zero, Address(addr, 1, post_indexed));
         __ subs(count, count, 1);
         __ b(L_cardtable_loop, ge);
+        __ BIND(L_done);
       }
       break;
     case BarrierSet::ModRef:
--- a/src/hotspot/cpu/ppc/c1_MacroAssembler_ppc.cpp	Wed Dec 06 15:14:13 2017 -0800
+++ b/src/hotspot/cpu/ppc/c1_MacroAssembler_ppc.cpp	Sat Dec 02 06:51:10 2017 +0100
@@ -41,20 +41,25 @@
 
 void C1_MacroAssembler::inline_cache_check(Register receiver, Register iCache) {
   const Register temp_reg = R12_scratch2;
+  Label Lmiss;
+
   verify_oop(receiver);
+  MacroAssembler::null_check(receiver, oopDesc::klass_offset_in_bytes(), &Lmiss);
   load_klass(temp_reg, receiver);
-  if (TrapBasedICMissChecks) {
+
+  if (TrapBasedICMissChecks && TrapBasedNullChecks) {
     trap_ic_miss_check(temp_reg, iCache);
   } else {
-    Label L;
+    Label Lok;
     cmpd(CCR0, temp_reg, iCache);
-    beq(CCR0, L);
+    beq(CCR0, Lok);
+    bind(Lmiss);
     //load_const_optimized(temp_reg, SharedRuntime::get_ic_miss_stub(), R0);
     calculate_address_from_global_toc(temp_reg, SharedRuntime::get_ic_miss_stub(), true, true, false);
     mtctr(temp_reg);
     bctr();
     align(32, 12);
-    bind(L);
+    bind(Lok);
   }
 }
 
--- a/src/hotspot/cpu/ppc/templateTable_ppc_64.cpp	Wed Dec 06 15:14:13 2017 -0800
+++ b/src/hotspot/cpu/ppc/templateTable_ppc_64.cpp	Sat Dec 02 06:51:10 2017 +0100
@@ -3371,7 +3371,7 @@
   __ testbitdi(CCR0, R0, Rflags, ConstantPoolCacheEntry::is_vfinal_shift);
   __ bfalse(CCR0, LnotFinal);
 
-  if (RewriteBytecodes && !UseSharedSpaces) {
+  if (RewriteBytecodes && !UseSharedSpaces && !DumpSharedSpaces) {
     patch_bytecode(Bytecodes::_fast_invokevfinal, Rnew_bc, R12_scratch2);
   }
   invokevfinal_helper(Rvtableindex_or_method, Rflags, R11_scratch1, R12_scratch2);
--- a/src/hotspot/cpu/s390/assembler_s390.hpp	Wed Dec 06 15:14:13 2017 -0800
+++ b/src/hotspot/cpu/s390/assembler_s390.hpp	Sat Dec 02 06:51:10 2017 +0100
@@ -582,7 +582,11 @@
 #define LOC_ZOPC    (unsigned long)(0xebL << 40 | 0xf2L)        // z196
 #define LOCG_ZOPC   (unsigned long)(0xebL << 40 | 0xe2L)        // z196
 
-#define LMG_ZOPC    (unsigned long)(235L << 40 | 4L)
+
+// LOAD multiple registers at once
+#define LM_ZOPC     (unsigned  int)(0x98  << 24)
+#define LMY_ZOPC    (unsigned long)(0xebL << 40 | 0x98L)
+#define LMG_ZOPC    (unsigned long)(0xebL << 40 | 0x04L)
 
 #define LE_ZOPC     (unsigned  int)(0x78 << 24)
 #define LEY_ZOPC    (unsigned long)(237L << 40 | 100L)
@@ -613,7 +617,10 @@
 #define STOC_ZOPC   (unsigned long)(0xebL << 40 | 0xf3L)        // z196
 #define STOCG_ZOPC  (unsigned long)(0xebL << 40 | 0xe3L)        // z196
 
-#define STMG_ZOPC   (unsigned long)(235L << 40 | 36L)
+// STORE multiple registers at once
+#define STM_ZOPC    (unsigned  int)(0x90  << 24)
+#define STMY_ZOPC   (unsigned long)(0xebL << 40 | 0x90L)
+#define STMG_ZOPC   (unsigned long)(0xebL << 40 | 0x24L)
 
 #define STE_ZOPC    (unsigned  int)(0x70 << 24)
 #define STEY_ZOPC   (unsigned long)(237L << 40 | 102L)
@@ -874,15 +881,19 @@
 
 // Shift
 // arithmetic
-#define SLA_ZOPC    (unsigned  int)(139 << 24)
-#define SLAG_ZOPC   (unsigned long)(235L << 40 | 11L)
-#define SRA_ZOPC    (unsigned  int)(138 << 24)
-#define SRAG_ZOPC   (unsigned long)(235L << 40 | 10L)
+#define SLA_ZOPC    (unsigned  int)(0x8b  << 24)
+#define SLAK_ZOPC   (unsigned long)(0xebL << 40 | 0xddL)
+#define SLAG_ZOPC   (unsigned long)(0xebL << 40 | 0x0bL)
+#define SRA_ZOPC    (unsigned  int)(0x8a  << 24)
+#define SRAK_ZOPC   (unsigned long)(0xebL << 40 | 0xdcL)
+#define SRAG_ZOPC   (unsigned long)(0xebL << 40 | 0x0aL)
 // logical
-#define SLL_ZOPC    (unsigned  int)(137 << 24)
-#define SLLG_ZOPC   (unsigned long)(235L << 40 | 13L)
-#define SRL_ZOPC    (unsigned  int)(136 << 24)
-#define SRLG_ZOPC   (unsigned long)(235L << 40 | 12L)
+#define SLL_ZOPC    (unsigned  int)(0x89  << 24)
+#define SLLK_ZOPC   (unsigned long)(0xebL << 40 | 0xdfL)
+#define SLLG_ZOPC   (unsigned long)(0xebL << 40 | 0x0dL)
+#define SRL_ZOPC    (unsigned  int)(0x88  << 24)
+#define SRLK_ZOPC   (unsigned long)(0xebL << 40 | 0xdeL)
+#define SRLG_ZOPC   (unsigned long)(0xebL << 40 | 0x0cL)
 
 // Rotate, then AND/XOR/OR/insert
 // rotate
@@ -2262,12 +2273,16 @@
 
   // shift
   inline void z_sla( Register r1,              int64_t d2, Register b2=Z_R0); // shift left  r1 = r1 << ((d2+b2)&0x3f) ; int32, only 31 bits shifted, sign preserved!
+  inline void z_slak(Register r1, Register r3, int64_t d2, Register b2=Z_R0); // shift left  r1 = r3 << ((d2+b2)&0x3f) ; int32, only 31 bits shifted, sign preserved!
   inline void z_slag(Register r1, Register r3, int64_t d2, Register b2=Z_R0); // shift left  r1 = r3 << ((d2+b2)&0x3f) ; int64, only 63 bits shifted, sign preserved!
   inline void z_sra( Register r1,              int64_t d2, Register b2=Z_R0); // shift right r1 = r1 >> ((d2+b2)&0x3f) ; int32, sign extended
+  inline void z_srak(Register r1, Register r3, int64_t d2, Register b2=Z_R0); // shift right r1 = r3 >> ((d2+b2)&0x3f) ; int32, sign extended
   inline void z_srag(Register r1, Register r3, int64_t d2, Register b2=Z_R0); // shift right r1 = r3 >> ((d2+b2)&0x3f) ; int64, sign extended
   inline void z_sll( Register r1,              int64_t d2, Register b2=Z_R0); // shift left  r1 = r1 << ((d2+b2)&0x3f) ; int32, zeros added
+  inline void z_sllk(Register r1, Register r3, int64_t d2, Register b2=Z_R0); // shift left  r1 = r3 << ((d2+b2)&0x3f) ; int32, zeros added
   inline void z_sllg(Register r1, Register r3, int64_t d2, Register b2=Z_R0); // shift left  r1 = r3 << ((d2+b2)&0x3f) ; int64, zeros added
   inline void z_srl( Register r1,              int64_t d2, Register b2=Z_R0); // shift right r1 = r1 >> ((d2+b2)&0x3f) ; int32, zero extended
+  inline void z_srlk(Register r1, Register r3, int64_t d2, Register b2=Z_R0); // shift right r1 = r3 >> ((d2+b2)&0x3f) ; int32, zero extended
   inline void z_srlg(Register r1, Register r3, int64_t d2, Register b2=Z_R0); // shift right r1 = r3 >> ((d2+b2)&0x3f) ; int64, zero extended
 
   // rotate
@@ -3035,7 +3050,11 @@
 
   inline void z_tam();
   inline void z_stckf(int64_t d2, Register b2);
+  inline void z_stm( Register r1, Register r3, int64_t d2, Register b2);
+  inline void z_stmy(Register r1, Register r3, int64_t d2, Register b2);
   inline void z_stmg(Register r1, Register r3, int64_t d2, Register b2);
+  inline void z_lm( Register r1, Register r3, int64_t d2, Register b2);
+  inline void z_lmy(Register r1, Register r3, int64_t d2, Register b2);
   inline void z_lmg(Register r1, Register r3, int64_t d2, Register b2);
 
   inline void z_cs( Register r1, Register r3, int64_t d2, Register b2);
--- a/src/hotspot/cpu/s390/assembler_s390.inline.hpp	Wed Dec 06 15:14:13 2017 -0800
+++ b/src/hotspot/cpu/s390/assembler_s390.inline.hpp	Sat Dec 02 06:51:10 2017 +0100
@@ -334,12 +334,16 @@
 // SHIFT/RORATE OPERATIONS
 //-----------------------------------
 inline void Assembler::z_sla( Register r1,              int64_t d2, Register b2) { emit_32( SLA_ZOPC  | regt(r1, 8, 32) | uimm12(d2, 20, 32) | reg(b2, 16, 32)); }
+inline void Assembler::z_slak(Register r1, Register r3, int64_t d2, Register b2) { emit_48( SLAK_ZOPC | regt(r1, 8, 48) | simm20(d2)         | reg(b2, 16, 48) | reg(r3, 12, 48)); }
 inline void Assembler::z_slag(Register r1, Register r3, int64_t d2, Register b2) { emit_48( SLAG_ZOPC | regt(r1, 8, 48) | simm20(d2)         | reg(b2, 16, 48) | reg(r3, 12, 48)); }
 inline void Assembler::z_sra( Register r1,              int64_t d2, Register b2) { emit_32( SRA_ZOPC  | regt(r1, 8, 32) | uimm12(d2, 20, 32) | reg(b2, 16, 32)); }
+inline void Assembler::z_srak(Register r1, Register r3, int64_t d2, Register b2) { emit_48( SRAK_ZOPC | regt(r1, 8, 48) | simm20(d2)         | reg(b2, 16, 48) | reg(r3, 12, 48)); }
 inline void Assembler::z_srag(Register r1, Register r3, int64_t d2, Register b2) { emit_48( SRAG_ZOPC | regt(r1, 8, 48) | simm20(d2)         | reg(b2, 16, 48) | reg(r3, 12, 48)); }
 inline void Assembler::z_sll( Register r1,              int64_t d2, Register b2) { emit_32( SLL_ZOPC  | regt(r1, 8, 32) | uimm12(d2, 20, 32) | reg(b2, 16, 32)); }
+inline void Assembler::z_sllk(Register r1, Register r3, int64_t d2, Register b2) { emit_48( SLLK_ZOPC | regt(r1, 8, 48) | simm20(d2)         | reg(b2, 16, 48) | reg(r3, 12, 48)); }
 inline void Assembler::z_sllg(Register r1, Register r3, int64_t d2, Register b2) { emit_48( SLLG_ZOPC | regt(r1, 8, 48) | simm20(d2)         | reg(b2, 16, 48) | reg(r3, 12, 48)); }
 inline void Assembler::z_srl( Register r1,              int64_t d2, Register b2) { emit_32( SRL_ZOPC  | regt(r1, 8, 32) | uimm12(d2, 20, 32) | reg(b2, 16, 32)); }
+inline void Assembler::z_srlk(Register r1, Register r3, int64_t d2, Register b2) { emit_48( SRLK_ZOPC | regt(r1, 8, 48) | simm20(d2)         | reg(b2, 16, 48) | reg(r3, 12, 48)); }
 inline void Assembler::z_srlg(Register r1, Register r3, int64_t d2, Register b2) { emit_48( SRLG_ZOPC | regt(r1, 8, 48) | simm20(d2)         | reg(b2, 16, 48) | reg(r3, 12, 48)); }
 
 // rotate left
@@ -690,10 +694,14 @@
 
 inline void Assembler::z_tam() { emit_16( TAM_ZOPC); }
 inline void Assembler::z_stckf(int64_t d2, Register b2) { emit_32( STCKF_ZOPC | uimm12(d2, 20, 32) | regz(b2, 16, 32)); }
-inline void Assembler::z_stmg(Register r1, Register r3, int64_t d2, Register b2) { emit_48( STMG_ZOPC | simm20(d2) | reg(r1, 8, 48) | reg(r3,12,48)| reg(b2,16,48) ); }
-inline void Assembler::z_lmg(Register r1, Register r3, int64_t d2, Register b2)  { emit_48( LMG_ZOPC  | simm20(d2) | reg(r1, 8, 48) | reg(r3,12,48)| reg(b2,16,48) ); }
+inline void Assembler::z_stm( Register r1, Register r3, int64_t d2, Register b2) { emit_32( STM_ZOPC  | reg(r1, 8, 32) | reg(r3,12,32)| reg(b2,16,32) | uimm12(d2, 20,32)); }
+inline void Assembler::z_stmy(Register r1, Register r3, int64_t d2, Register b2) { emit_48( STMY_ZOPC | reg(r1, 8, 48) | reg(r3,12,48)| reg(b2,16,48) | simm20(d2) ); }
+inline void Assembler::z_stmg(Register r1, Register r3, int64_t d2, Register b2) { emit_48( STMG_ZOPC | reg(r1, 8, 48) | reg(r3,12,48)| reg(b2,16,48) | simm20(d2) ); }
+inline void Assembler::z_lm(  Register r1, Register r3, int64_t d2, Register b2) { emit_32( LM_ZOPC   | reg(r1, 8, 32) | reg(r3,12,32)| reg(b2,16,32) | uimm12(d2, 20,32)); }
+inline void Assembler::z_lmy( Register r1, Register r3, int64_t d2, Register b2) { emit_48( LMY_ZOPC  | reg(r1, 8, 48) | reg(r3,12,48)| reg(b2,16,48) | simm20(d2) ); }
+inline void Assembler::z_lmg( Register r1, Register r3, int64_t d2, Register b2) { emit_48( LMG_ZOPC  | reg(r1, 8, 48) | reg(r3,12,48)| reg(b2,16,48) | simm20(d2) ); }
 
-inline void Assembler::z_cs(Register r1, Register r3, int64_t d2, Register b2)  { emit_32( CS_ZOPC  | regt(r1, 8, 32) | reg(r3, 12, 32) | reg(b2, 16, 32) | uimm12(d2, 20, 32)); }
+inline void Assembler::z_cs( Register r1, Register r3, int64_t d2, Register b2) { emit_32( CS_ZOPC  | regt(r1, 8, 32) | reg(r3, 12, 32) | reg(b2, 16, 32) | uimm12(d2, 20, 32)); }
 inline void Assembler::z_csy(Register r1, Register r3, int64_t d2, Register b2) { emit_48( CSY_ZOPC | regt(r1, 8, 48) | reg(r3, 12, 48) | reg(b2, 16, 48) | simm20(d2)); }
 inline void Assembler::z_csg(Register r1, Register r3, int64_t d2, Register b2) { emit_48( CSG_ZOPC | regt(r1, 8, 48) | reg(r3, 12, 48) | reg(b2, 16, 48) | simm20(d2)); }
 inline void Assembler::z_cs( Register r1, Register r3, const Address& a) { assert(!a.has_index(), "Cannot encode index"); z_cs( r1, r3, a.disp(), a.baseOrR0()); }
--- a/src/hotspot/cpu/s390/macroAssembler_s390.cpp	Wed Dec 06 15:14:13 2017 -0800
+++ b/src/hotspot/cpu/s390/macroAssembler_s390.cpp	Sat Dec 02 06:51:10 2017 +0100
@@ -936,7 +936,7 @@
 
   // Some extra safety net.
   if (!RelAddr::is_in_range_of_RelAddr32(total_distance)) {
-    guarantee(RelAddr::is_in_range_of_RelAddr32(total_distance), "too far away");
+    guarantee(RelAddr::is_in_range_of_RelAddr32(total_distance), "load_long_pcrelative can't handle distance " INTPTR_FORMAT, total_distance);
   }
 
   (this)->relocate(rspec, relocInfo::pcrel_addr_format);
@@ -956,7 +956,7 @@
 
   // Some extra safety net.
   if (!RelAddr::is_in_range_of_RelAddr32(total_distance)) {
-    guarantee(RelAddr::is_in_range_of_RelAddr32(total_distance), "too far away");
+    guarantee(RelAddr::is_in_range_of_RelAddr32(total_distance), "load_long_pcrelative can't handle distance " INTPTR_FORMAT, total_distance);
   }
 
   (this)->relocate(rspec, relocInfo::pcrel_addr_format);
@@ -1025,6 +1025,13 @@
   }
 }
 
+void MacroAssembler::prefetch_read(Address a) {
+  z_pfd(1, a.disp20(), a.indexOrR0(), a.base());
+}
+void MacroAssembler::prefetch_update(Address a) {
+  z_pfd(2, a.disp20(), a.indexOrR0(), a.base());
+}
+
 // Clear a register, i.e. load const zero into reg.
 // Return len (in bytes) of generated instruction(s).
 // whole_reg: Clear 64 bits if true, 32 bits otherwise.
@@ -4896,77 +4903,296 @@
 
 // Intrinsics for CompactStrings
 
-// Compress char[] to byte[]. odd_reg contains cnt. Kills dst. Early clobber: result
+// Compress char[] to byte[].
+//   Restores: src, dst
+//   Uses:     cnt
+//   Kills:    tmp, Z_R0, Z_R1.
+//   Early clobber: result.
+// Note:
+//   cnt is signed int. Do not rely on high word!
+//       counts # characters, not bytes.
 // The result is the number of characters copied before the first incompatible character was found.
-// If tmp2 is provided and the compression fails, the compression stops exactly at this point and the result is precise.
+// If precise is true, the processing stops exactly at this point. Otherwise, the result may be off
+// by a few bytes. The result always indicates the number of copied characters.
 //
 // Note: Does not behave exactly like package private StringUTF16 compress java implementation in case of failure:
-// - Different number of characters may have been written to dead array (if tmp2 not provided).
+// - Different number of characters may have been written to dead array (if precise is false).
 // - Returns a number <cnt instead of 0. (Result gets compared with cnt.)
-unsigned int MacroAssembler::string_compress(Register result, Register src, Register dst, Register odd_reg,
-                                             Register even_reg, Register tmp, Register tmp2) {
-  int block_start = offset();
-  Label Lloop1, Lloop2, Lslow, Ldone;
-  const Register addr2 = dst, ind1 = result, mask = tmp;
-  const bool precise = (tmp2 != noreg);
-
-  BLOCK_COMMENT("string_compress {");
-
-  z_sll(odd_reg, 1);       // Number of bytes to read. (Must be a positive simm32.)
-  clear_reg(ind1);         // Index to read.
-  z_llilf(mask, 0xFF00FF00);
-  z_ahi(odd_reg, -16);     // Last possible index for fast loop.
-  z_brl(Lslow);
-
-  // ind1: index, even_reg: index increment, odd_reg: index limit
-  z_iihf(mask, 0xFF00FF00);
-  z_lhi(even_reg, 16);
-
-  bind(Lloop1); // 8 Characters per iteration.
-  z_lg(Z_R0, Address(src, ind1));
-  z_lg(Z_R1, Address(src, ind1, 8));
+unsigned int MacroAssembler::string_compress(Register result, Register src, Register dst, Register cnt,
+                                             Register tmp,    bool precise) {
+  assert_different_registers(Z_R0, Z_R1, src, dst, cnt, tmp);
+
   if (precise) {
+    BLOCK_COMMENT("encode_iso_array {");
+  } else {
+    BLOCK_COMMENT("string_compress {");
+  }
+  int  block_start = offset();
+
+  Register       Rsrc  = src;
+  Register       Rdst  = dst;
+  Register       Rix   = tmp;
+  Register       Rcnt  = cnt;
+  Register       Rmask = result;  // holds incompatibility check mask until result value is stored.
+  Label          ScalarShortcut, AllDone;
+
+  z_iilf(Rmask, 0xFF00FF00);
+  z_iihf(Rmask, 0xFF00FF00);
+
+#if 0  // Sacrifice shortcuts for code compactness
+  {
+    //---<  shortcuts for short strings (very frequent)   >---
+    //   Strings with 4 and 8 characters were fond to occur very frequently.
+    //   Therefore, we handle them right away with minimal overhead.
+    Label     skipShortcut, skip4Shortcut, skip8Shortcut;
+    Register  Rout = Z_R0;
+    z_chi(Rcnt, 4);
+    z_brne(skip4Shortcut);                 // 4 characters are very frequent
+      z_lg(Z_R0, 0, Rsrc);                 // Treat exactly 4 characters specially.
+      if (VM_Version::has_DistinctOpnds()) {
+        Rout = Z_R0;
+        z_ngrk(Rix, Z_R0, Rmask);
+      } else {
+        Rout = Rix;
+        z_lgr(Rix, Z_R0);
+        z_ngr(Z_R0, Rmask);
+      }
+      z_brnz(skipShortcut);
+      z_stcmh(Rout, 5, 0, Rdst);
+      z_stcm(Rout,  5, 2, Rdst);
+      z_lgfr(result, Rcnt);
+      z_bru(AllDone);
+    bind(skip4Shortcut);
+
+    z_chi(Rcnt, 8);
+    z_brne(skip8Shortcut);                 // There's more to do...
+      z_lmg(Z_R0, Z_R1, 0, Rsrc);          // Treat exactly 8 characters specially.
+      if (VM_Version::has_DistinctOpnds()) {
+        Rout = Z_R0;
+        z_ogrk(Rix, Z_R0, Z_R1);
+        z_ngr(Rix, Rmask);
+      } else {
+        Rout = Rix;
+        z_lgr(Rix, Z_R0);
+        z_ogr(Z_R0, Z_R1);
+        z_ngr(Z_R0, Rmask);
+      }
+      z_brnz(skipShortcut);
+      z_stcmh(Rout, 5, 0, Rdst);
+      z_stcm(Rout,  5, 2, Rdst);
+      z_stcmh(Z_R1, 5, 4, Rdst);
+      z_stcm(Z_R1,  5, 6, Rdst);
+      z_lgfr(result, Rcnt);
+      z_bru(AllDone);
+
+    bind(skip8Shortcut);
+    clear_reg(Z_R0, true, false);          // #characters already processed (none). Precond for scalar loop.
+    z_brl(ScalarShortcut);                 // Just a few characters
+
+    bind(skipShortcut);
+  }
+#endif
+  clear_reg(Z_R0);                         // make sure register is properly initialized.
+
+  if (VM_Version::has_VectorFacility()) {
+    const int  min_vcnt     = 32;          // Minimum #characters required to use vector instructions.
+                                           // Otherwise just do nothing in vector mode.
+                                           // Must be multiple of 2*(vector register length in chars (8 HW = 128 bits)).
+    const int  log_min_vcnt = exact_log2(min_vcnt);
+    Label      VectorLoop, VectorDone, VectorBreak;
+
+    VectorRegister Vtmp1      = Z_V16;
+    VectorRegister Vtmp2      = Z_V17;
+    VectorRegister Vmask      = Z_V18;
+    VectorRegister Vzero      = Z_V19;
+    VectorRegister Vsrc_first = Z_V20;
+    VectorRegister Vsrc_last  = Z_V23;
+
+    assert((Vsrc_last->encoding() - Vsrc_first->encoding() + 1) == min_vcnt/8, "logic error");
+    assert(VM_Version::has_DistinctOpnds(), "Assumption when has_VectorFacility()");
+    z_srak(Rix, Rcnt, log_min_vcnt);       // # vector loop iterations
+    z_brz(VectorDone);                     // not enough data for vector loop
+
+    z_vzero(Vzero);                        // all zeroes
+    z_vgmh(Vmask, 0, 7);                   // generate 0xff00 mask for all 2-byte elements
+    z_sllg(Z_R0, Rix, log_min_vcnt);       // remember #chars that will be processed by vector loop
+
+    bind(VectorLoop);
+      z_vlm(Vsrc_first, Vsrc_last, 0, Rsrc);
+      add2reg(Rsrc, min_vcnt*2);
+
+      //---<  check for incompatible character  >---
+      z_vo(Vtmp1, Z_V20, Z_V21);
+      z_vo(Vtmp2, Z_V22, Z_V23);
+      z_vo(Vtmp1, Vtmp1, Vtmp2);
+      z_vn(Vtmp1, Vtmp1, Vmask);
+      z_vceqhs(Vtmp1, Vtmp1, Vzero);       // high half of all chars must be zero for successful compress.
+      z_brne(VectorBreak);                 // break vector loop, incompatible character found.
+                                           // re-process data from current iteration in break handler.
+
+      //---<  pack & store characters  >---
+      z_vpkh(Vtmp1, Z_V20, Z_V21);         // pack (src1, src2) -> tmp1
+      z_vpkh(Vtmp2, Z_V22, Z_V23);         // pack (src3, src4) -> tmp2
+      z_vstm(Vtmp1, Vtmp2, 0, Rdst);       // store packed string
+      add2reg(Rdst, min_vcnt);
+
+      z_brct(Rix, VectorLoop);
+
+    z_bru(VectorDone);
+
+    bind(VectorBreak);
+      add2reg(Rsrc, -min_vcnt*2);          // Fix Rsrc. Rsrc was already updated, but Rdst and Rix are not.
+      z_sll(Rix, log_min_vcnt);            // # chars processed so far in VectorLoop, excl. current iteration.
+      z_sr(Z_R0, Rix);                     // correct # chars processed in total.
+
+    bind(VectorDone);
+  }
+
+  {
+    const int  min_cnt     =  8;           // Minimum #characters required to use unrolled loop.
+                                           // Otherwise just do nothing in unrolled loop.
+                                           // Must be multiple of 8.
+    const int  log_min_cnt = exact_log2(min_cnt);
+    Label      UnrolledLoop, UnrolledDone, UnrolledBreak;
+
     if (VM_Version::has_DistinctOpnds()) {
-      z_ogrk(tmp2, Z_R0, Z_R1);
+      z_srk(Rix, Rcnt, Z_R0);              // remaining # chars to compress in unrolled loop
     } else {
-      z_lgr(tmp2, Z_R0);
-      z_ogr(tmp2, Z_R1);
+      z_lr(Rix, Rcnt);
+      z_sr(Rix, Z_R0);
     }
-    z_ngr(tmp2, mask);
-    z_brne(Lslow);         // Failed fast case, retry slowly.
-  }
-  z_stcmh(Z_R0, 5, 0, addr2);
-  z_stcm(Z_R0, 5, 2, addr2);
-  if (!precise) { z_ogr(Z_R0, Z_R1); }
-  z_stcmh(Z_R1, 5, 4, addr2);
-  z_stcm(Z_R1, 5, 6, addr2);
-  if (!precise) {
-    z_ngr(Z_R0, mask);
-    z_brne(Ldone);         // Failed (more than needed was written).
-  }
-  z_aghi(addr2, 8);
-  z_brxle(ind1, even_reg, Lloop1);
-
-  bind(Lslow);
-  // Compute index limit and skip if negative.
-  z_ahi(odd_reg, 16-2);    // Last possible index for slow loop.
-  z_lhi(even_reg, 2);
-  z_cr(ind1, odd_reg);
-  z_brh(Ldone);
-
-  bind(Lloop2); // 1 Character per iteration.
-  z_llh(Z_R0, Address(src, ind1));
-  z_tmll(Z_R0, 0xFF00);
-  z_brnaz(Ldone);          // Failed slow case: Return number of written characters.
-  z_stc(Z_R0, Address(addr2));
-  z_aghi(addr2, 1);
-  z_brxle(ind1, even_reg, Lloop2);
-
-  bind(Ldone);             // result = ind1 = 2*cnt
-  z_srl(ind1, 1);
-
-  BLOCK_COMMENT("} string_compress");
-
+    z_sra(Rix, log_min_cnt);             // unrolled loop count
+    z_brz(UnrolledDone);
+
+    bind(UnrolledLoop);
+      z_lmg(Z_R0, Z_R1, 0, Rsrc);
+      if (precise) {
+        z_ogr(Z_R1, Z_R0);                 // check all 8 chars for incompatibility
+        z_ngr(Z_R1, Rmask);
+        z_brnz(UnrolledBreak);
+
+        z_lg(Z_R1, 8, Rsrc);               // reload destroyed register
+        z_stcmh(Z_R0, 5, 0, Rdst);
+        z_stcm(Z_R0,  5, 2, Rdst);
+      } else {
+        z_stcmh(Z_R0, 5, 0, Rdst);
+        z_stcm(Z_R0,  5, 2, Rdst);
+
+        z_ogr(Z_R0, Z_R1);
+        z_ngr(Z_R0, Rmask);
+        z_brnz(UnrolledBreak);
+      }
+      z_stcmh(Z_R1, 5, 4, Rdst);
+      z_stcm(Z_R1,  5, 6, Rdst);
+
+      add2reg(Rsrc, min_cnt*2);
+      add2reg(Rdst, min_cnt);
+      z_brct(Rix, UnrolledLoop);
+
+    z_lgfr(Z_R0, Rcnt);                    // # chars processed in total after unrolled loop.
+    z_nilf(Z_R0, ~(min_cnt-1));
+    z_tmll(Rcnt, min_cnt-1);
+    z_brnaz(ScalarShortcut);               // if all bits zero, there is nothing left to do for scalar loop.
+                                           // Rix == 0 in all cases.
+    z_lgfr(result, Rcnt);                  // all characters processed.
+    z_sgfr(Rdst, Rcnt);                    // restore ptr
+    z_sgfr(Rsrc, Rcnt);                    // restore ptr, double the element count for Rsrc restore
+    z_sgfr(Rsrc, Rcnt);
+    z_bru(AllDone);
+
+    bind(UnrolledBreak);
+    z_lgfr(Z_R0, Rcnt);                    // # chars processed in total after unrolled loop
+    z_nilf(Z_R0, ~(min_cnt-1));
+    z_sll(Rix, log_min_cnt);               // # chars processed so far in UnrolledLoop, excl. current iteration.
+    z_sr(Z_R0, Rix);                       // correct # chars processed in total.
+    if (!precise) {
+      z_lgfr(result, Z_R0);
+      z_aghi(result, min_cnt/2);           // min_cnt/2 characters have already been written
+                                           // but ptrs were not updated yet.
+      z_sgfr(Rdst, Z_R0);                  // restore ptr
+      z_sgfr(Rsrc, Z_R0);                  // restore ptr, double the element count for Rsrc restore
+      z_sgfr(Rsrc, Z_R0);
+      z_bru(AllDone);
+    }
+    bind(UnrolledDone);
+  }
+
+  {
+    Label     ScalarLoop, ScalarDone, ScalarBreak;
+
+    bind(ScalarShortcut);
+    z_ltgfr(result, Rcnt);
+    z_brz(AllDone);
+
+#if 0  // Sacrifice shortcuts for code compactness
+    {
+      //---<  Special treatment for very short strings (one or two characters)  >---
+      //   For these strings, we are sure that the above code was skipped.
+      //   Thus, no registers were modified, register restore is not required.
+      Label     ScalarDoit, Scalar2Char;
+      z_chi(Rcnt, 2);
+      z_brh(ScalarDoit);
+      z_llh(Z_R1,  0, Z_R0, Rsrc);
+      z_bre(Scalar2Char);
+      z_tmll(Z_R1, 0xff00);
+      z_lghi(result, 0);                   // cnt == 1, first char invalid, no chars successfully processed
+      z_brnaz(AllDone);
+      z_stc(Z_R1,  0, Z_R0, Rdst);
+      z_lghi(result, 1);
+      z_bru(AllDone);
+
+      bind(Scalar2Char);
+      z_llh(Z_R0,  2, Z_R0, Rsrc);
+      z_tmll(Z_R1, 0xff00);
+      z_lghi(result, 0);                   // cnt == 2, first char invalid, no chars successfully processed
+      z_brnaz(AllDone);
+      z_stc(Z_R1,  0, Z_R0, Rdst);
+      z_tmll(Z_R0, 0xff00);
+      z_lghi(result, 1);                   // cnt == 2, second char invalid, one char successfully processed
+      z_brnaz(AllDone);
+      z_stc(Z_R0,  1, Z_R0, Rdst);
+      z_lghi(result, 2);
+      z_bru(AllDone);
+
+      bind(ScalarDoit);
+    }
+#endif
+
+    if (VM_Version::has_DistinctOpnds()) {
+      z_srk(Rix, Rcnt, Z_R0);              // remaining # chars to compress in unrolled loop
+    } else {
+      z_lr(Rix, Rcnt);
+      z_sr(Rix, Z_R0);
+    }
+    z_lgfr(result, Rcnt);                  // # processed characters (if all runs ok).
+    z_brz(ScalarDone);
+
+    bind(ScalarLoop);
+      z_llh(Z_R1, 0, Z_R0, Rsrc);
+      z_tmll(Z_R1, 0xff00);
+      z_brnaz(ScalarBreak);
+      z_stc(Z_R1, 0, Z_R0, Rdst);
+      add2reg(Rsrc, 2);
+      add2reg(Rdst, 1);
+      z_brct(Rix, ScalarLoop);
+
+    z_bru(ScalarDone);
+
+    bind(ScalarBreak);
+    z_sr(result, Rix);
+
+    bind(ScalarDone);
+    z_sgfr(Rdst, result);                  // restore ptr
+    z_sgfr(Rsrc, result);                  // restore ptr, double the element count for Rsrc restore
+    z_sgfr(Rsrc, result);
+  }
+  bind(AllDone);
+
+  if (precise) {
+    BLOCK_COMMENT("} encode_iso_array");
+  } else {
+    BLOCK_COMMENT("} string_compress");
+  }
   return offset() - block_start;
 }
 
@@ -4997,53 +5223,432 @@
   return offset() - block_start;
 }
 
-// Inflate byte[] to char[]. odd_reg contains cnt. Kills src.
-unsigned int MacroAssembler::string_inflate(Register src, Register dst, Register odd_reg,
-                                            Register even_reg, Register tmp) {
+// Inflate byte[] to char[].
+//   Restores: src, dst
+//   Uses:     cnt
+//   Kills:    tmp, Z_R0, Z_R1.
+// Note:
+//   cnt is signed int. Do not rely on high word!
+//       counts # characters, not bytes.
+unsigned int MacroAssembler::string_inflate(Register src, Register dst, Register cnt, Register tmp) {
+  assert_different_registers(Z_R0, Z_R1, src, dst, cnt, tmp);
+
+  BLOCK_COMMENT("string_inflate {");
   int block_start = offset();
 
-  BLOCK_COMMENT("string_inflate {");
-
-  Label Lloop1, Lloop2, Lslow, Ldone;
-  const Register addr1 = src, ind2 = tmp;
-
-  z_sll(odd_reg, 1);       // Number of bytes to write. (Must be a positive simm32.)
-  clear_reg(ind2);         // Index to write.
-  z_ahi(odd_reg, -16);     // Last possible index for fast loop.
-  z_brl(Lslow);
-
-  // ind2: index, even_reg: index increment, odd_reg: index limit
-  clear_reg(Z_R0);
-  clear_reg(Z_R1);
-  z_lhi(even_reg, 16);
-
-  bind(Lloop1); // 8 Characters per iteration.
-  z_icmh(Z_R0, 5, 0, addr1);
-  z_icmh(Z_R1, 5, 4, addr1);
-  z_icm(Z_R0, 5, 2, addr1);
-  z_icm(Z_R1, 5, 6, addr1);
-  z_aghi(addr1, 8);
-  z_stg(Z_R0, Address(dst, ind2));
-  z_stg(Z_R1, Address(dst, ind2, 8));
-  z_brxle(ind2, even_reg, Lloop1);
-
-  bind(Lslow);
-  // Compute index limit and skip if negative.
-  z_ahi(odd_reg, 16-2);    // Last possible index for slow loop.
-  z_lhi(even_reg, 2);
-  z_cr(ind2, odd_reg);
-  z_brh(Ldone);
-
-  bind(Lloop2); // 1 Character per iteration.
-  z_llc(Z_R0, Address(addr1));
-  z_sth(Z_R0, Address(dst, ind2));
-  z_aghi(addr1, 1);
-  z_brxle(ind2, even_reg, Lloop2);
-
-  bind(Ldone);
+  Register   Rcnt = cnt;   // # characters (src: bytes, dst: char (2-byte)), remaining after current loop.
+  Register   Rix  = tmp;   // loop index
+  Register   Rsrc = src;   // addr(src array)
+  Register   Rdst = dst;   // addr(dst array)
+  Label      ScalarShortcut, AllDone;
+
+#if 0  // Sacrifice shortcuts for code compactness
+  {
+    //---<  shortcuts for short strings (very frequent)   >---
+    Label   skipShortcut, skip4Shortcut;
+    z_ltr(Rcnt, Rcnt);                     // absolutely nothing to do for strings of len == 0.
+    z_brz(AllDone);
+    clear_reg(Z_R0);                       // make sure registers are properly initialized.
+    clear_reg(Z_R1);
+    z_chi(Rcnt, 4);
+    z_brne(skip4Shortcut);                 // 4 characters are very frequent
+      z_icm(Z_R0, 5,    0, Rsrc);          // Treat exactly 4 characters specially.
+      z_icm(Z_R1, 5,    2, Rsrc);
+      z_stm(Z_R0, Z_R1, 0, Rdst);
+      z_bru(AllDone);
+    bind(skip4Shortcut);
+
+    z_chi(Rcnt, 8);
+    z_brh(skipShortcut);                   // There's a lot to do...
+    z_lgfr(Z_R0, Rcnt);                    // remaining #characters (<= 8). Precond for scalar loop.
+                                           // This does not destroy the "register cleared" state of Z_R0.
+    z_brl(ScalarShortcut);                 // Just a few characters
+      z_icmh(Z_R0, 5, 0, Rsrc);            // Treat exactly 8 characters specially.
+      z_icmh(Z_R1, 5, 4, Rsrc);
+      z_icm(Z_R0,  5, 2, Rsrc);
+      z_icm(Z_R1,  5, 6, Rsrc);
+      z_stmg(Z_R0, Z_R1, 0, Rdst);
+      z_bru(AllDone);
+    bind(skipShortcut);
+  }
+#endif
+  clear_reg(Z_R0);                         // make sure register is properly initialized.
+
+  if (VM_Version::has_VectorFacility()) {
+    const int  min_vcnt     = 32;          // Minimum #characters required to use vector instructions.
+                                           // Otherwise just do nothing in vector mode.
+                                           // Must be multiple of vector register length (16 bytes = 128 bits).
+    const int  log_min_vcnt = exact_log2(min_vcnt);
+    Label      VectorLoop, VectorDone;
+
+    assert(VM_Version::has_DistinctOpnds(), "Assumption when has_VectorFacility()");
+    z_srak(Rix, Rcnt, log_min_vcnt);       // calculate # vector loop iterations
+    z_brz(VectorDone);                     // skip if none
+
+    z_sllg(Z_R0, Rix, log_min_vcnt);       // remember #chars that will be processed by vector loop
+
+    bind(VectorLoop);
+      z_vlm(Z_V20, Z_V21, 0, Rsrc);        // get next 32 characters (single-byte)
+      add2reg(Rsrc, min_vcnt);
+
+      z_vuplhb(Z_V22, Z_V20);              // V2 <- (expand) V0(high)
+      z_vupllb(Z_V23, Z_V20);              // V3 <- (expand) V0(low)
+      z_vuplhb(Z_V24, Z_V21);              // V4 <- (expand) V1(high)
+      z_vupllb(Z_V25, Z_V21);              // V5 <- (expand) V1(low)
+      z_vstm(Z_V22, Z_V25, 0, Rdst);       // store next 32 bytes
+      add2reg(Rdst, min_vcnt*2);
+
+      z_brct(Rix, VectorLoop);
+
+    bind(VectorDone);
+  }
+
+  const int  min_cnt     =  8;             // Minimum #characters required to use unrolled scalar loop.
+                                           // Otherwise just do nothing in unrolled scalar mode.
+                                           // Must be multiple of 8.
+  {
+    const int  log_min_cnt = exact_log2(min_cnt);
+    Label      UnrolledLoop, UnrolledDone;
+
+
+    if (VM_Version::has_DistinctOpnds()) {
+      z_srk(Rix, Rcnt, Z_R0);              // remaining # chars to process in unrolled loop
+    } else {
+      z_lr(Rix, Rcnt);
+      z_sr(Rix, Z_R0);
+    }
+    z_sra(Rix, log_min_cnt);               // unrolled loop count
+    z_brz(UnrolledDone);
+
+    clear_reg(Z_R0);
+    clear_reg(Z_R1);
+
+    bind(UnrolledLoop);
+      z_icmh(Z_R0, 5, 0, Rsrc);
+      z_icmh(Z_R1, 5, 4, Rsrc);
+      z_icm(Z_R0,  5, 2, Rsrc);
+      z_icm(Z_R1,  5, 6, Rsrc);
+      add2reg(Rsrc, min_cnt);
+
+      z_stmg(Z_R0, Z_R1, 0, Rdst);
+
+      add2reg(Rdst, min_cnt*2);
+      z_brct(Rix, UnrolledLoop);
+
+    bind(UnrolledDone);
+    z_lgfr(Z_R0, Rcnt);                    // # chars left over after unrolled loop.
+    z_nilf(Z_R0, min_cnt-1);
+    z_brnz(ScalarShortcut);                // if zero, there is nothing left to do for scalar loop.
+                                           // Rix == 0 in all cases.
+    z_sgfr(Z_R0, Rcnt);                    // negative # characters the ptrs have been advanced previously.
+    z_agr(Rdst, Z_R0);                     // restore ptr, double the element count for Rdst restore.
+    z_agr(Rdst, Z_R0);
+    z_agr(Rsrc, Z_R0);                     // restore ptr.
+    z_bru(AllDone);
+  }
+
+  {
+    bind(ScalarShortcut);
+    // Z_R0 must contain remaining # characters as 64-bit signed int here.
+    //      register contents is preserved over scalar processing (for register fixup).
+
+#if 0  // Sacrifice shortcuts for code compactness
+    {
+      Label      ScalarDefault;
+      z_chi(Rcnt, 2);
+      z_brh(ScalarDefault);
+      z_llc(Z_R0,  0, Z_R0, Rsrc);     // 6 bytes
+      z_sth(Z_R0,  0, Z_R0, Rdst);     // 4 bytes
+      z_brl(AllDone);
+      z_llc(Z_R0,  1, Z_R0, Rsrc);     // 6 bytes
+      z_sth(Z_R0,  2, Z_R0, Rdst);     // 4 bytes
+      z_bru(AllDone);
+      bind(ScalarDefault);
+    }
+#endif
+
+    Label   CodeTable;
+    // Some comments on Rix calculation:
+    //  - Rcnt is small, therefore no bits shifted out of low word (sll(g) instructions).
+    //  - high word of both Rix and Rcnt may contain garbage
+    //  - the final lngfr takes care of that garbage, extending the sign to high word
+    z_sllg(Rix, Z_R0, 2);                // calculate 10*Rix = (4*Rix + Rix)*2
+    z_ar(Rix, Z_R0);
+    z_larl(Z_R1, CodeTable);
+    z_sll(Rix, 1);
+    z_lngfr(Rix, Rix);      // ix range: [0..7], after inversion & mult: [-(7*12)..(0*12)].
+    z_bc(Assembler::bcondAlways, 0, Rix, Z_R1);
+
+    z_llc(Z_R1,  6, Z_R0, Rsrc);  // 6 bytes
+    z_sth(Z_R1, 12, Z_R0, Rdst);  // 4 bytes
+
+    z_llc(Z_R1,  5, Z_R0, Rsrc);
+    z_sth(Z_R1, 10, Z_R0, Rdst);
+
+    z_llc(Z_R1,  4, Z_R0, Rsrc);
+    z_sth(Z_R1,  8, Z_R0, Rdst);
+
+    z_llc(Z_R1,  3, Z_R0, Rsrc);
+    z_sth(Z_R1,  6, Z_R0, Rdst);
+
+    z_llc(Z_R1,  2, Z_R0, Rsrc);
+    z_sth(Z_R1,  4, Z_R0, Rdst);
+
+    z_llc(Z_R1,  1, Z_R0, Rsrc);
+    z_sth(Z_R1,  2, Z_R0, Rdst);
+
+    z_llc(Z_R1,  0, Z_R0, Rsrc);
+    z_sth(Z_R1,  0, Z_R0, Rdst);
+    bind(CodeTable);
+
+    z_chi(Rcnt, 8);                        // no fixup for small strings. Rdst, Rsrc were not modified.
+    z_brl(AllDone);
+
+    z_sgfr(Z_R0, Rcnt);                    // # characters the ptrs have been advanced previously.
+    z_agr(Rdst, Z_R0);                     // restore ptr, double the element count for Rdst restore.
+    z_agr(Rdst, Z_R0);
+    z_agr(Rsrc, Z_R0);                     // restore ptr.
+  }
+  bind(AllDone);
 
   BLOCK_COMMENT("} string_inflate");
-
+  return offset() - block_start;
+}
+
+// Inflate byte[] to char[], length known at compile time.
+//   Restores: src, dst
+//   Kills:    tmp, Z_R0, Z_R1.
+// Note:
+//   len is signed int. Counts # characters, not bytes.
+unsigned int MacroAssembler::string_inflate_const(Register src, Register dst, Register tmp, int len) {
+  assert_different_registers(Z_R0, Z_R1, src, dst, tmp);
+
+  BLOCK_COMMENT("string_inflate_const {");
+  int block_start = offset();
+
+  Register   Rix  = tmp;   // loop index
+  Register   Rsrc = src;   // addr(src array)
+  Register   Rdst = dst;   // addr(dst array)
+  Label      ScalarShortcut, AllDone;
+  int        nprocessed = 0;
+  int        src_off    = 0;  // compensate for saved (optimized away) ptr advancement.
+  int        dst_off    = 0;  // compensate for saved (optimized away) ptr advancement.
+  bool       restore_inputs = false;
+  bool       workreg_clear  = false;
+
+  if ((len >= 32) && VM_Version::has_VectorFacility()) {
+    const int  min_vcnt     = 32;          // Minimum #characters required to use vector instructions.
+                                           // Otherwise just do nothing in vector mode.
+                                           // Must be multiple of vector register length (16 bytes = 128 bits).
+    const int  log_min_vcnt = exact_log2(min_vcnt);
+    const int  iterations   = (len - nprocessed) >> log_min_vcnt;
+    nprocessed             += iterations << log_min_vcnt;
+    Label      VectorLoop;
+
+    if (iterations == 1) {
+      z_vlm(Z_V20, Z_V21, 0+src_off, Rsrc);  // get next 32 characters (single-byte)
+      z_vuplhb(Z_V22, Z_V20);                // V2 <- (expand) V0(high)
+      z_vupllb(Z_V23, Z_V20);                // V3 <- (expand) V0(low)
+      z_vuplhb(Z_V24, Z_V21);                // V4 <- (expand) V1(high)
+      z_vupllb(Z_V25, Z_V21);                // V5 <- (expand) V1(low)
+      z_vstm(Z_V22, Z_V25, 0+dst_off, Rdst); // store next 32 bytes
+
+      src_off += min_vcnt;
+      dst_off += min_vcnt*2;
+    } else {
+      restore_inputs = true;
+
+      z_lgfi(Rix, len>>log_min_vcnt);
+      bind(VectorLoop);
+        z_vlm(Z_V20, Z_V21, 0, Rsrc);        // get next 32 characters (single-byte)
+        add2reg(Rsrc, min_vcnt);
+
+        z_vuplhb(Z_V22, Z_V20);              // V2 <- (expand) V0(high)
+        z_vupllb(Z_V23, Z_V20);              // V3 <- (expand) V0(low)
+        z_vuplhb(Z_V24, Z_V21);              // V4 <- (expand) V1(high)
+        z_vupllb(Z_V25, Z_V21);              // V5 <- (expand) V1(low)
+        z_vstm(Z_V22, Z_V25, 0, Rdst);       // store next 32 bytes
+        add2reg(Rdst, min_vcnt*2);
+
+        z_brct(Rix, VectorLoop);
+    }
+  }
+
+  if (((len-nprocessed) >= 16) && VM_Version::has_VectorFacility()) {
+    const int  min_vcnt     = 16;          // Minimum #characters required to use vector instructions.
+                                           // Otherwise just do nothing in vector mode.
+                                           // Must be multiple of vector register length (16 bytes = 128 bits).
+    const int  log_min_vcnt = exact_log2(min_vcnt);
+    const int  iterations   = (len - nprocessed) >> log_min_vcnt;
+    nprocessed             += iterations << log_min_vcnt;
+    assert(iterations == 1, "must be!");
+
+    z_vl(Z_V20, 0+src_off, Z_R0, Rsrc);    // get next 16 characters (single-byte)
+    z_vuplhb(Z_V22, Z_V20);                // V2 <- (expand) V0(high)
+    z_vupllb(Z_V23, Z_V20);                // V3 <- (expand) V0(low)
+    z_vstm(Z_V22, Z_V23, 0+dst_off, Rdst); // store next 32 bytes
+
+    src_off += min_vcnt;
+    dst_off += min_vcnt*2;
+  }
+
+  if ((len-nprocessed) > 8) {
+    const int  min_cnt     =  8;           // Minimum #characters required to use unrolled scalar loop.
+                                           // Otherwise just do nothing in unrolled scalar mode.
+                                           // Must be multiple of 8.
+    const int  log_min_cnt = exact_log2(min_cnt);
+    const int  iterations  = (len - nprocessed) >> log_min_cnt;
+    nprocessed     += iterations << log_min_cnt;
+
+    //---<  avoid loop overhead/ptr increment for small # iterations  >---
+    if (iterations <= 2) {
+      clear_reg(Z_R0);
+      clear_reg(Z_R1);
+      workreg_clear = true;
+
+      z_icmh(Z_R0, 5, 0+src_off, Rsrc);
+      z_icmh(Z_R1, 5, 4+src_off, Rsrc);
+      z_icm(Z_R0,  5, 2+src_off, Rsrc);
+      z_icm(Z_R1,  5, 6+src_off, Rsrc);
+      z_stmg(Z_R0, Z_R1, 0+dst_off, Rdst);
+
+      src_off += min_cnt;
+      dst_off += min_cnt*2;
+    }
+
+    if (iterations == 2) {
+      z_icmh(Z_R0, 5, 0+src_off, Rsrc);
+      z_icmh(Z_R1, 5, 4+src_off, Rsrc);
+      z_icm(Z_R0,  5, 2+src_off, Rsrc);
+      z_icm(Z_R1,  5, 6+src_off, Rsrc);
+      z_stmg(Z_R0, Z_R1, 0+dst_off, Rdst);
+
+      src_off += min_cnt;
+      dst_off += min_cnt*2;
+    }
+
+    if (iterations > 2) {
+      Label      UnrolledLoop;
+      restore_inputs  = true;
+
+      clear_reg(Z_R0);
+      clear_reg(Z_R1);
+      workreg_clear = true;
+
+      z_lgfi(Rix, iterations);
+      bind(UnrolledLoop);
+        z_icmh(Z_R0, 5, 0, Rsrc);
+        z_icmh(Z_R1, 5, 4, Rsrc);
+        z_icm(Z_R0,  5, 2, Rsrc);
+        z_icm(Z_R1,  5, 6, Rsrc);
+        add2reg(Rsrc, min_cnt);
+
+        z_stmg(Z_R0, Z_R1, 0, Rdst);
+        add2reg(Rdst, min_cnt*2);
+
+        z_brct(Rix, UnrolledLoop);
+    }
+  }
+
+  if ((len-nprocessed) > 0) {
+    switch (len-nprocessed) {
+      case 8:
+        if (!workreg_clear) {
+          clear_reg(Z_R0);
+          clear_reg(Z_R1);
+        }
+        z_icmh(Z_R0, 5, 0+src_off, Rsrc);
+        z_icmh(Z_R1, 5, 4+src_off, Rsrc);
+        z_icm(Z_R0,  5, 2+src_off, Rsrc);
+        z_icm(Z_R1,  5, 6+src_off, Rsrc);
+        z_stmg(Z_R0, Z_R1, 0+dst_off, Rdst);
+        break;
+      case 7:
+        if (!workreg_clear) {
+          clear_reg(Z_R0);
+          clear_reg(Z_R1);
+        }
+        clear_reg(Rix);
+        z_icm(Z_R0,  5, 0+src_off, Rsrc);
+        z_icm(Z_R1,  5, 2+src_off, Rsrc);
+        z_icm(Rix,   5, 4+src_off, Rsrc);
+        z_stm(Z_R0,  Z_R1, 0+dst_off, Rdst);
+        z_llc(Z_R0,  6+src_off, Z_R0, Rsrc);
+        z_st(Rix,    8+dst_off, Z_R0, Rdst);
+        z_sth(Z_R0, 12+dst_off, Z_R0, Rdst);
+        break;
+      case 6:
+        if (!workreg_clear) {
+          clear_reg(Z_R0);
+          clear_reg(Z_R1);
+        }
+        clear_reg(Rix);
+        z_icm(Z_R0, 5, 0+src_off, Rsrc);
+        z_icm(Z_R1, 5, 2+src_off, Rsrc);
+        z_icm(Rix,  5, 4+src_off, Rsrc);
+        z_stm(Z_R0, Z_R1, 0+dst_off, Rdst);
+        z_st(Rix,   8+dst_off, Z_R0, Rdst);
+        break;
+      case 5:
+        if (!workreg_clear) {
+          clear_reg(Z_R0);
+          clear_reg(Z_R1);
+        }
+        z_icm(Z_R0, 5, 0+src_off, Rsrc);
+        z_icm(Z_R1, 5, 2+src_off, Rsrc);
+        z_llc(Rix,  4+src_off, Z_R0, Rsrc);
+        z_stm(Z_R0, Z_R1, 0+dst_off, Rdst);
+        z_sth(Rix,  8+dst_off, Z_R0, Rdst);
+        break;
+      case 4:
+        if (!workreg_clear) {
+          clear_reg(Z_R0);
+          clear_reg(Z_R1);
+        }
+        z_icm(Z_R0, 5, 0+src_off, Rsrc);
+        z_icm(Z_R1, 5, 2+src_off, Rsrc);
+        z_stm(Z_R0, Z_R1, 0+dst_off, Rdst);
+        break;
+      case 3:
+        if (!workreg_clear) {
+          clear_reg(Z_R0);
+        }
+        z_llc(Z_R1, 2+src_off, Z_R0, Rsrc);
+        z_icm(Z_R0, 5, 0+src_off, Rsrc);
+        z_sth(Z_R1, 4+dst_off, Z_R0, Rdst);
+        z_st(Z_R0,  0+dst_off, Rdst);
+        break;
+      case 2:
+        z_llc(Z_R0, 0+src_off, Z_R0, Rsrc);
+        z_llc(Z_R1, 1+src_off, Z_R0, Rsrc);
+        z_sth(Z_R0, 0+dst_off, Z_R0, Rdst);
+        z_sth(Z_R1, 2+dst_off, Z_R0, Rdst);
+        break;
+      case 1:
+        z_llc(Z_R0, 0+src_off, Z_R0, Rsrc);
+        z_sth(Z_R0, 0+dst_off, Z_R0, Rdst);
+        break;
+      default:
+        guarantee(false, "Impossible");
+        break;
+    }
+    src_off   +=  len-nprocessed;
+    dst_off   += (len-nprocessed)*2;
+    nprocessed = len;
+  }
+
+  //---< restore modified input registers  >---
+  if ((nprocessed > 0) && restore_inputs) {
+    z_agfi(Rsrc, -(nprocessed-src_off));
+    if (nprocessed < 1000000000) { // avoid int overflow
+      z_agfi(Rdst, -(nprocessed*2-dst_off));
+    } else {
+      z_agfi(Rdst, -(nprocessed-dst_off));
+      z_agfi(Rdst, -nprocessed);
+    }
+  }
+
+  BLOCK_COMMENT("} string_inflate_const");
   return offset() - block_start;
 }
 
--- a/src/hotspot/cpu/s390/macroAssembler_s390.hpp	Wed Dec 06 15:14:13 2017 -0800
+++ b/src/hotspot/cpu/s390/macroAssembler_s390.hpp	Sat Dec 02 06:51:10 2017 +0100
@@ -198,6 +198,9 @@
   // Test a bit in a register. Result is reflected in CC.
   void testbit(Register r, unsigned int bitPos);
 
+  void prefetch_read(Address a);
+  void prefetch_update(Address a);
+
   // Clear a register, i.e. load const zero into reg. Return len (in bytes) of
   // generated instruction(s).
   //   whole_reg: Clear 64 bits if true, 32 bits otherwise.
@@ -836,7 +839,7 @@
   void load_mirror(Register mirror, Register method);
 
   //--------------------------
-  //---  perations on arrays.
+  //---  Operations on arrays.
   //--------------------------
   unsigned int Clear_Array(Register cnt_arg, Register base_pointer_arg, Register src_addr, Register src_len);
   unsigned int Clear_Array_Const(long cnt, Register base);
@@ -849,20 +852,34 @@
   // Special String Intrinsics Implementation.
   //-------------------------------------------
   // Intrinsics for CompactStrings
-  // Compress char[] to byte[]. odd_reg contains cnt. tmp3 is only needed for precise behavior in failure case. Kills dst.
-  unsigned int string_compress(Register result, Register src, Register dst, Register odd_reg,
-                               Register even_reg, Register tmp, Register tmp2 = noreg);
+  //   Restores: src, dst
+  //   Uses:     cnt
+  //   Kills:    tmp, Z_R0, Z_R1.
+  //   Early clobber: result.
+  //   Boolean precise controls accuracy of result value.
+  unsigned int string_compress(Register result, Register src, Register dst, Register cnt,
+                               Register tmp,    bool precise);
+
+  // Inflate byte[] to char[].
+  unsigned int string_inflate_trot(Register src, Register dst, Register cnt, Register tmp);
+
+  // Inflate byte[] to char[].
+  //   Restores: src, dst
+  //   Uses:     cnt
+  //   Kills:    tmp, Z_R0, Z_R1.
+  unsigned int string_inflate(Register src, Register dst, Register cnt, Register tmp);
+
+  // Inflate byte[] to char[], length known at compile time.
+  //   Restores: src, dst
+  //   Kills:    tmp, Z_R0, Z_R1.
+  // Note:
+  //   len is signed int. Counts # characters, not bytes.
+  unsigned int string_inflate_const(Register src, Register dst, Register tmp, int len);
 
   // Kills src.
   unsigned int has_negatives(Register result, Register src, Register cnt,
                              Register odd_reg, Register even_reg, Register tmp);
 
-  // Inflate byte[] to char[].
-  unsigned int string_inflate_trot(Register src, Register dst, Register cnt, Register tmp);
-  // Odd_reg contains cnt. Kills src.
-  unsigned int string_inflate(Register src, Register dst, Register odd_reg,
-                              Register even_reg, Register tmp);
-
   unsigned int string_compare(Register str1, Register str2, Register cnt1, Register cnt2,
                               Register odd_reg, Register even_reg, Register result, int ae);
 
--- a/src/hotspot/cpu/s390/s390.ad	Wed Dec 06 15:14:13 2017 -0800
+++ b/src/hotspot/cpu/s390/s390.ad	Sat Dec 02 06:51:10 2017 +0100
@@ -10267,14 +10267,14 @@
 %}
 
 // char[] to byte[] compression
-instruct string_compress(iRegP src, rarg5RegP dst, iRegI result, roddRegI len, revenRegI evenReg, iRegI tmp, flagsReg cr) %{
+instruct string_compress(iRegP src, iRegP dst, iRegI result, iRegI len, iRegI tmp, flagsReg cr) %{
   match(Set result (StrCompressedCopy src (Binary dst len)));
-  effect(TEMP_DEF result, USE_KILL dst, USE_KILL len, TEMP evenReg, TEMP tmp, KILL cr); // R0, R1 are killed, too.
+  effect(TEMP_DEF result, TEMP tmp, KILL cr); // R0, R1 are killed, too.
   ins_cost(300);
   format %{ "String Compress $src->$dst($len) -> $result" %}
   ins_encode %{
     __ string_compress($result$$Register, $src$$Register, $dst$$Register, $len$$Register,
-                       $evenReg$$Register, $tmp$$Register);
+                       $tmp$$Register, false);
   %}
   ins_pipe(pipe_class_dummy);
 %}
@@ -10293,13 +10293,25 @@
 //%}
 
 // byte[] to char[] inflation
-instruct string_inflate(Universe dummy, rarg5RegP src, iRegP dst, roddRegI len, revenRegI evenReg, iRegI tmp, flagsReg cr) %{
+instruct string_inflate(Universe dummy, iRegP src, iRegP dst, iRegI len, iRegI tmp, flagsReg cr) %{
   match(Set dummy (StrInflatedCopy src (Binary dst len)));
-  effect(USE_KILL src, USE_KILL len, TEMP evenReg, TEMP tmp, KILL cr); // R0, R1 are killed, too.
+  effect(TEMP tmp, KILL cr); // R0, R1 are killed, too.
   ins_cost(300);
   format %{ "String Inflate $src->$dst($len)" %}
   ins_encode %{
-    __ string_inflate($src$$Register, $dst$$Register, $len$$Register, $evenReg$$Register, $tmp$$Register);
+    __ string_inflate($src$$Register, $dst$$Register, $len$$Register, $tmp$$Register);
+  %}
+  ins_pipe(pipe_class_dummy);
+%}
+
+// byte[] to char[] inflation
+instruct string_inflate_const(Universe dummy, iRegP src, iRegP dst, iRegI tmp, immI len, flagsReg cr) %{
+  match(Set dummy (StrInflatedCopy src (Binary dst len)));
+  effect(TEMP tmp, KILL cr); // R0, R1 are killed, too.
+  ins_cost(300);
+  format %{ "String Inflate (constLen) $src->$dst($len)" %}
+  ins_encode %{
+    __ string_inflate_const($src$$Register, $dst$$Register, $tmp$$Register, $len$$constant);
   %}
   ins_pipe(pipe_class_dummy);
 %}
@@ -10318,14 +10330,14 @@
 %}
 
 // encode char[] to byte[] in ISO_8859_1
-instruct encode_iso_array(rarg5RegP src, iRegP dst, iRegI result, roddRegI len, revenRegI evenReg, iRegI tmp, iRegI tmp2, flagsReg cr) %{
+instruct encode_iso_array(iRegP src, iRegP dst, iRegI result, iRegI len, iRegI tmp, flagsReg cr) %{
   match(Set result (EncodeISOArray src (Binary dst len)));
-  effect(TEMP_DEF result, USE_KILL src, USE_KILL len, TEMP evenReg, TEMP tmp, TEMP tmp2, KILL cr); // R0, R1 are killed, too.
+  effect(TEMP_DEF result, TEMP tmp, KILL cr); // R0, R1 are killed, too.
   ins_cost(300);
   format %{ "Encode array $src->$dst($len) -> $result" %}
   ins_encode %{
     __ string_compress($result$$Register, $src$$Register, $dst$$Register, $len$$Register,
-                       $evenReg$$Register, $tmp$$Register, $tmp2$$Register);
+                       $tmp$$Register, true);
   %}
   ins_pipe(pipe_class_dummy);
 %}
--- a/src/hotspot/cpu/s390/templateTable_s390.cpp	Wed Dec 06 15:14:13 2017 -0800
+++ b/src/hotspot/cpu/s390/templateTable_s390.cpp	Sat Dec 02 06:51:10 2017 +0100
@@ -2884,12 +2884,12 @@
   // ztos
   BTB_BEGIN(is_Bool, bsize, "putfield_or_static:is_Bool");
   __ pop(ztos);
-  if (do_rewrite) {
+  if (!is_static) {
     pop_and_check_object(obj);
   }
   __ z_nilf(Z_tos, 0x1);
   __ z_stc(Z_tos, field);
-  if (!is_static) {
+  if (do_rewrite) {
     patch_bytecode(Bytecodes::_fast_zputfield, bc, Z_ARG5, true, byte_no);
   }
   __ z_bru(Done);
--- a/src/hotspot/cpu/sparc/c1_LIRAssembler_sparc.cpp	Wed Dec 06 15:14:13 2017 -0800
+++ b/src/hotspot/cpu/sparc/c1_LIRAssembler_sparc.cpp	Sat Dec 02 06:51:10 2017 +0100
@@ -398,8 +398,13 @@
   if (o == NULL) {
     __ set(NULL_WORD, reg);
   } else {
+#ifdef ASSERT
+    {
+      ThreadInVMfromNative tiv(JavaThread::current());
+      assert(Universe::heap()->is_in_reserved(JNIHandles::resolve(o)), "should be real oop");
+    }
+#endif
     int oop_index = __ oop_recorder()->find_index(o);
-    assert(Universe::heap()->is_in_reserved(JNIHandles::resolve(o)), "should be real oop");
     RelocationHolder rspec = oop_Relocation::spec(oop_index);
     __ set(NULL_WORD, reg, rspec); // Will be set when the nmethod is created
   }
--- a/src/hotspot/cpu/sparc/stubGenerator_sparc.cpp	Wed Dec 06 15:14:13 2017 -0800
+++ b/src/hotspot/cpu/sparc/stubGenerator_sparc.cpp	Sat Dec 02 06:51:10 2017 +0100
@@ -898,7 +898,9 @@
           assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code");
           assert_different_registers(addr, count, tmp);
 
-          Label L_loop;
+          Label L_loop, L_done;
+
+          __ cmp_and_br_short(count, 0, Assembler::equal, Assembler::pt, L_done); // zero count - nothing to do
 
           __ sll_ptr(count, LogBytesPerHeapOop, count);
           __ sub(count, BytesPerHeapOop, count);
@@ -914,6 +916,7 @@
           __ subcc(count, 1, count);
           __ brx(Assembler::greaterEqual, false, Assembler::pt, L_loop);
           __ delayed()->add(addr, 1, addr);
+        __ BIND(L_done);
         }
         break;
       case BarrierSet::ModRef:
--- a/src/hotspot/cpu/x86/assembler_x86.cpp	Wed Dec 06 15:14:13 2017 -0800
+++ b/src/hotspot/cpu/x86/assembler_x86.cpp	Sat Dec 02 06:51:10 2017 +0100
@@ -1256,7 +1256,7 @@
 
 void Assembler::addsd(XMMRegister dst, XMMRegister src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
-  InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
   attributes.set_rex_vex_w_reverted();
   int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
   emit_int8(0x58);
@@ -1266,7 +1266,7 @@
 void Assembler::addsd(XMMRegister dst, Address src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
   InstructionMark im(this);
-  InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
   attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_64bit);
   attributes.set_rex_vex_w_reverted();
   simd_prefix(dst, dst, src, VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
@@ -1276,7 +1276,7 @@
 
 void Assembler::addss(XMMRegister dst, XMMRegister src) {
   NOT_LP64(assert(VM_Version::supports_sse(), ""));
-  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
   int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
   emit_int8(0x58);
   emit_int8((unsigned char)(0xC0 | encode));
@@ -1285,7 +1285,7 @@
 void Assembler::addss(XMMRegister dst, Address src) {
   NOT_LP64(assert(VM_Version::supports_sse(), ""));
   InstructionMark im(this);
-  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
   attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_32bit);
   simd_prefix(dst, dst, src, VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
   emit_int8(0x58);
@@ -1295,7 +1295,7 @@
 void Assembler::aesdec(XMMRegister dst, Address src) {
   assert(VM_Version::supports_aes(), "");
   InstructionMark im(this);
-  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
   simd_prefix(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
   emit_int8((unsigned char)0xDE);
   emit_operand(dst, src);
@@ -1303,7 +1303,7 @@
 
 void Assembler::aesdec(XMMRegister dst, XMMRegister src) {
   assert(VM_Version::supports_aes(), "");
-  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
   int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
   emit_int8((unsigned char)0xDE);
   emit_int8(0xC0 | encode);
@@ -1312,7 +1312,7 @@
 void Assembler::aesdeclast(XMMRegister dst, Address src) {
   assert(VM_Version::supports_aes(), "");
   InstructionMark im(this);
-  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
   simd_prefix(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
   emit_int8((unsigned char)0xDF);
   emit_operand(dst, src);
@@ -1320,7 +1320,7 @@
 
 void Assembler::aesdeclast(XMMRegister dst, XMMRegister src) {
   assert(VM_Version::supports_aes(), "");
-  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
   int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
   emit_int8((unsigned char)0xDF);
   emit_int8((unsigned char)(0xC0 | encode));
@@ -1329,7 +1329,7 @@
 void Assembler::aesenc(XMMRegister dst, Address src) {
   assert(VM_Version::supports_aes(), "");
   InstructionMark im(this);
-  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
   simd_prefix(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
   emit_int8((unsigned char)0xDC);
   emit_operand(dst, src);
@@ -1337,7 +1337,7 @@
 
 void Assembler::aesenc(XMMRegister dst, XMMRegister src) {
   assert(VM_Version::supports_aes(), "");
-  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
   int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
   emit_int8((unsigned char)0xDC);
   emit_int8(0xC0 | encode);
@@ -1346,7 +1346,7 @@
 void Assembler::aesenclast(XMMRegister dst, Address src) {
   assert(VM_Version::supports_aes(), "");
   InstructionMark im(this);
-  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
   simd_prefix(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
   emit_int8((unsigned char)0xDD);
   emit_operand(dst, src);
@@ -1354,7 +1354,7 @@
 
 void Assembler::aesenclast(XMMRegister dst, XMMRegister src) {
   assert(VM_Version::supports_aes(), "");
-  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
   int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
   emit_int8((unsigned char)0xDD);
   emit_int8((unsigned char)(0xC0 | encode));
@@ -1387,7 +1387,7 @@
 
 void Assembler::andnl(Register dst, Register src1, Register src2) {
   assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported");
-  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
   int encode = vex_prefix_and_encode(dst->encoding(), src1->encoding(), src2->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_38, &attributes);
   emit_int8((unsigned char)0xF2);
   emit_int8((unsigned char)(0xC0 | encode));
@@ -1396,7 +1396,7 @@
 void Assembler::andnl(Register dst, Register src1, Address src2) {
   assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported");
   InstructionMark im(this);
-  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
   vex_prefix(src2, src1->encoding(), dst->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_38, &attributes);
   emit_int8((unsigned char)0xF2);
   emit_operand(dst, src2);
@@ -1424,7 +1424,7 @@
 
 void Assembler::blsil(Register dst, Register src) {
   assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported");
-  InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
   int encode = vex_prefix_and_encode(rbx->encoding(), dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_38, &attributes);
   emit_int8((unsigned char)0xF3);
   emit_int8((unsigned char)(0xC0 | encode));
@@ -1433,7 +1433,7 @@
 void Assembler::blsil(Register dst, Address src) {
   assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported");
   InstructionMark im(this);
-  InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
   vex_prefix(src, dst->encoding(), rbx->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_38, &attributes);
   emit_int8((unsigned char)0xF3);
   emit_operand(rbx, src);
@@ -1441,7 +1441,7 @@
 
 void Assembler::blsmskl(Register dst, Register src) {
   assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported");
-  InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
   int encode = vex_prefix_and_encode(rdx->encoding(), dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_38, &attributes);
   emit_int8((unsigned char)0xF3);
   emit_int8((unsigned char)(0xC0 | encode));
@@ -1450,7 +1450,7 @@
 void Assembler::blsmskl(Register dst, Address src) {
   assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported");
   InstructionMark im(this);
-  InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
   vex_prefix(src, dst->encoding(), rdx->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_38, &attributes);
   emit_int8((unsigned char)0xF3);
   emit_operand(rdx, src);
@@ -1458,7 +1458,7 @@
 
 void Assembler::blsrl(Register dst, Register src) {
   assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported");
-  InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
   int encode = vex_prefix_and_encode(rcx->encoding(), dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_38, &attributes);
   emit_int8((unsigned char)0xF3);
   emit_int8((unsigned char)(0xC0 | encode));
@@ -1467,7 +1467,7 @@
 void Assembler::blsrl(Register dst, Address src) {
   assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported");
   InstructionMark im(this);
-  InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
   vex_prefix(src, dst->encoding(), rcx->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_38, &attributes);
   emit_int8((unsigned char)0xF3);
   emit_operand(rcx, src);
@@ -1753,7 +1753,7 @@
 
 void Assembler::cvtsd2ss(XMMRegister dst, XMMRegister src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
-  InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
   attributes.set_rex_vex_w_reverted();
   int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
   emit_int8(0x5A);
@@ -1763,7 +1763,7 @@
 void Assembler::cvtsd2ss(XMMRegister dst, Address src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
   InstructionMark im(this);
-  InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
   attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_64bit);
   attributes.set_rex_vex_w_reverted();
   simd_prefix(dst, dst, src, VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
@@ -1817,7 +1817,7 @@
 
 void Assembler::cvtss2sd(XMMRegister dst, XMMRegister src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
-  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
   int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
   emit_int8(0x5A);
   emit_int8((unsigned char)(0xC0 | encode));
@@ -1826,7 +1826,7 @@
 void Assembler::cvtss2sd(XMMRegister dst, Address src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
   InstructionMark im(this);
-  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
   attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_32bit);
   simd_prefix(dst, dst, src, VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
   emit_int8(0x5A);
@@ -1870,7 +1870,7 @@
 void Assembler::divsd(XMMRegister dst, Address src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
   InstructionMark im(this);
-  InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
   attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_64bit);
   attributes.set_rex_vex_w_reverted();
   simd_prefix(dst, dst, src, VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
@@ -1880,7 +1880,7 @@
 
 void Assembler::divsd(XMMRegister dst, XMMRegister src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
-  InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
   attributes.set_rex_vex_w_reverted();
   int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
   emit_int8(0x5E);
@@ -1890,7 +1890,7 @@
 void Assembler::divss(XMMRegister dst, Address src) {
   NOT_LP64(assert(VM_Version::supports_sse(), ""));
   InstructionMark im(this);
-  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
   attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_32bit);
   simd_prefix(dst, dst, src, VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
   emit_int8(0x5E);
@@ -1899,7 +1899,7 @@
 
 void Assembler::divss(XMMRegister dst, XMMRegister src) {
   NOT_LP64(assert(VM_Version::supports_sse(), ""));
-  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
   int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
   emit_int8(0x5E);
   emit_int8((unsigned char)(0xC0 | encode));
@@ -2105,7 +2105,7 @@
 void Assembler::ldmxcsr( Address src) {
   if (UseAVX > 0 ) {
     InstructionMark im(this);
-    InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ false, /* uses_vl */ false);
+    InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
     vex_prefix(src, 0, 0, VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
     emit_int8((unsigned char)0xAE);
     emit_operand(as_Register(2), src);
@@ -2784,7 +2784,7 @@
 
 void Assembler::movsd(XMMRegister dst, XMMRegister src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
-  InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
   attributes.set_rex_vex_w_reverted();
   int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
   emit_int8(0x10);
@@ -2794,7 +2794,7 @@
 void Assembler::movsd(XMMRegister dst, Address src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
   InstructionMark im(this);
-  InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
   attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_64bit);
   attributes.set_rex_vex_w_reverted();
   simd_prefix(dst, xnoreg, src, VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
@@ -2805,7 +2805,7 @@
 void Assembler::movsd(Address dst, XMMRegister src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
   InstructionMark im(this);
-  InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
   attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_64bit);
   attributes.reset_is_clear_context();
   attributes.set_rex_vex_w_reverted();
@@ -2816,7 +2816,7 @@
 
 void Assembler::movss(XMMRegister dst, XMMRegister src) {
   NOT_LP64(assert(VM_Version::supports_sse(), ""));
-  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
   int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
   emit_int8(0x10);
   emit_int8((unsigned char)(0xC0 | encode));
@@ -2825,7 +2825,7 @@
 void Assembler::movss(XMMRegister dst, Address src) {
   NOT_LP64(assert(VM_Version::supports_sse(), ""));
   InstructionMark im(this);
-  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
   attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_32bit);
   simd_prefix(dst, xnoreg, src, VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
   emit_int8(0x10);
@@ -2835,7 +2835,7 @@
 void Assembler::movss(Address dst, XMMRegister src) {
   NOT_LP64(assert(VM_Version::supports_sse(), ""));
   InstructionMark im(this);
-  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
   attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_32bit);
   attributes.reset_is_clear_context();
   simd_prefix(src, xnoreg, dst, VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
@@ -2931,7 +2931,7 @@
 void Assembler::mulsd(XMMRegister dst, Address src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
   InstructionMark im(this);
-  InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
   attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_64bit);
   attributes.set_rex_vex_w_reverted();
   simd_prefix(dst, dst, src, VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
@@ -2941,7 +2941,7 @@
 
 void Assembler::mulsd(XMMRegister dst, XMMRegister src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
-  InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
   attributes.set_rex_vex_w_reverted();
   int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
   emit_int8(0x59);
@@ -2951,7 +2951,7 @@
 void Assembler::mulss(XMMRegister dst, Address src) {
   NOT_LP64(assert(VM_Version::supports_sse(), ""));
   InstructionMark im(this);
-  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
   attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_32bit);
   simd_prefix(dst, dst, src, VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
   emit_int8(0x59);
@@ -2960,7 +2960,7 @@
 
 void Assembler::mulss(XMMRegister dst, XMMRegister src) {
   NOT_LP64(assert(VM_Version::supports_sse(), ""));
-  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
   int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
   emit_int8(0x59);
   emit_int8((unsigned char)(0xC0 | encode));
@@ -4289,7 +4289,7 @@
 
 void Assembler::pblendw(XMMRegister dst, XMMRegister src, int imm8) {
   assert(VM_Version::supports_sse4_1(), "");
-  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
   int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
   emit_int8((unsigned char)0x0E);
   emit_int8((unsigned char)(0xC0 | encode));
@@ -4388,7 +4388,7 @@
 
 void Assembler::sqrtsd(XMMRegister dst, XMMRegister src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
-  InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
   attributes.set_rex_vex_w_reverted();
   int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
   emit_int8(0x51);
@@ -4398,7 +4398,7 @@
 void Assembler::sqrtsd(XMMRegister dst, Address src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
   InstructionMark im(this);
-  InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
   attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_64bit);
   attributes.set_rex_vex_w_reverted();
   simd_prefix(dst, dst, src, VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
@@ -4408,7 +4408,7 @@
 
 void Assembler::sqrtss(XMMRegister dst, XMMRegister src) {
   NOT_LP64(assert(VM_Version::supports_sse(), ""));
-  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
   int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
   emit_int8(0x51);
   emit_int8((unsigned char)(0xC0 | encode));
@@ -4421,7 +4421,7 @@
 void Assembler::sqrtss(XMMRegister dst, Address src) {
   NOT_LP64(assert(VM_Version::supports_sse(), ""));
   InstructionMark im(this);
-  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
   attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_32bit);
   simd_prefix(dst, dst, src, VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
   emit_int8(0x51);
@@ -4484,7 +4484,7 @@
 
 void Assembler::subsd(XMMRegister dst, XMMRegister src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
-  InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
   attributes.set_rex_vex_w_reverted();
   int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
   emit_int8(0x5C);
@@ -4494,7 +4494,7 @@
 void Assembler::subsd(XMMRegister dst, Address src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
   InstructionMark im(this);
-  InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
   attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_64bit);
   attributes.set_rex_vex_w_reverted();
   simd_prefix(dst, dst, src, VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
@@ -4504,7 +4504,7 @@
 
 void Assembler::subss(XMMRegister dst, XMMRegister src) {
   NOT_LP64(assert(VM_Version::supports_sse(), ""));
-  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false , /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true , /* uses_vl */ false);
   int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
   emit_int8(0x5C);
   emit_int8((unsigned char)(0xC0 | encode));
@@ -4513,7 +4513,7 @@
 void Assembler::subss(XMMRegister dst, Address src) {
   NOT_LP64(assert(VM_Version::supports_sse(), ""));
   InstructionMark im(this);
-  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
   attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_32bit);
   simd_prefix(dst, dst, src, VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
   emit_int8(0x5C);
@@ -4735,7 +4735,7 @@
 void Assembler::vaddsd(XMMRegister dst, XMMRegister nds, Address src) {
   assert(VM_Version::supports_avx(), "");
   InstructionMark im(this);
-  InstructionAttr attributes(AVX_128bit, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
   attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_64bit);
   attributes.set_rex_vex_w_reverted();
   vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
@@ -4745,7 +4745,7 @@
 
 void Assembler::vaddsd(XMMRegister dst, XMMRegister nds, XMMRegister src) {
   assert(VM_Version::supports_avx(), "");
-  InstructionAttr attributes(AVX_128bit, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
   attributes.set_rex_vex_w_reverted();
   int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
   emit_int8(0x58);
@@ -4755,7 +4755,7 @@
 void Assembler::vaddss(XMMRegister dst, XMMRegister nds, Address src) {
   assert(VM_Version::supports_avx(), "");
   InstructionMark im(this);
-  InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
   attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_32bit);
   vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
   emit_int8(0x58);
@@ -4764,7 +4764,7 @@
 
 void Assembler::vaddss(XMMRegister dst, XMMRegister nds, XMMRegister src) {
   assert(VM_Version::supports_avx(), "");
-  InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
   int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
   emit_int8(0x58);
   emit_int8((unsigned char)(0xC0 | encode));
@@ -4773,7 +4773,7 @@
 void Assembler::vdivsd(XMMRegister dst, XMMRegister nds, Address src) {
   assert(VM_Version::supports_avx(), "");
   InstructionMark im(this);
-  InstructionAttr attributes(AVX_128bit, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
   attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_64bit);
   attributes.set_rex_vex_w_reverted();
   vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
@@ -4783,7 +4783,7 @@
 
 void Assembler::vdivsd(XMMRegister dst, XMMRegister nds, XMMRegister src) {
   assert(VM_Version::supports_avx(), "");
-  InstructionAttr attributes(AVX_128bit, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
   attributes.set_rex_vex_w_reverted();
   int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
   emit_int8(0x5E);
@@ -4793,7 +4793,7 @@
 void Assembler::vdivss(XMMRegister dst, XMMRegister nds, Address src) {
   assert(VM_Version::supports_avx(), "");
   InstructionMark im(this);
-  InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
   attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_32bit);
   vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
   emit_int8(0x5E);
@@ -4802,7 +4802,7 @@
 
 void Assembler::vdivss(XMMRegister dst, XMMRegister nds, XMMRegister src) {
   assert(VM_Version::supports_avx(), "");
-  InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
   int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
   emit_int8(0x5E);
   emit_int8((unsigned char)(0xC0 | encode));
@@ -4810,7 +4810,7 @@
 
 void Assembler::vfmadd231sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
   assert(VM_Version::supports_fma(), "");
-  InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
   int encode = vex_prefix_and_encode(dst->encoding(), src1->encoding(), src2->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
   emit_int8((unsigned char)0xB9);
   emit_int8((unsigned char)(0xC0 | encode));
@@ -4818,7 +4818,7 @@
 
 void Assembler::vfmadd231ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
   assert(VM_Version::supports_fma(), "");
-  InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
   int encode = vex_prefix_and_encode(dst->encoding(), src1->encoding(), src2->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
   emit_int8((unsigned char)0xB9);
   emit_int8((unsigned char)(0xC0 | encode));
@@ -4827,7 +4827,7 @@
 void Assembler::vmulsd(XMMRegister dst, XMMRegister nds, Address src) {
   assert(VM_Version::supports_avx(), "");
   InstructionMark im(this);
-  InstructionAttr attributes(AVX_128bit, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
   attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_64bit);
   attributes.set_rex_vex_w_reverted();
   vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
@@ -4837,7 +4837,7 @@
 
 void Assembler::vmulsd(XMMRegister dst, XMMRegister nds, XMMRegister src) {
   assert(VM_Version::supports_avx(), "");
-  InstructionAttr attributes(AVX_128bit, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
   attributes.set_rex_vex_w_reverted();
   int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
   emit_int8(0x59);
@@ -4847,7 +4847,7 @@
 void Assembler::vmulss(XMMRegister dst, XMMRegister nds, Address src) {
   assert(VM_Version::supports_avx(), "");
   InstructionMark im(this);
-  InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
   attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_32bit);
   vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
   emit_int8(0x59);
@@ -4856,7 +4856,7 @@
 
 void Assembler::vmulss(XMMRegister dst, XMMRegister nds, XMMRegister src) {
   assert(VM_Version::supports_avx(), "");
-  InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
   int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
   emit_int8(0x59);
   emit_int8((unsigned char)(0xC0 | encode));
@@ -4865,7 +4865,7 @@
 void Assembler::vsubsd(XMMRegister dst, XMMRegister nds, Address src) {
   assert(VM_Version::supports_avx(), "");
   InstructionMark im(this);
-  InstructionAttr attributes(AVX_128bit, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
   attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_64bit);
   attributes.set_rex_vex_w_reverted();
   vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
@@ -4875,7 +4875,7 @@
 
 void Assembler::vsubsd(XMMRegister dst, XMMRegister nds, XMMRegister src) {
   assert(VM_Version::supports_avx(), "");
-  InstructionAttr attributes(AVX_128bit, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
   attributes.set_rex_vex_w_reverted();
   int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
   emit_int8(0x5C);
@@ -4885,7 +4885,7 @@
 void Assembler::vsubss(XMMRegister dst, XMMRegister nds, Address src) {
   assert(VM_Version::supports_avx(), "");
   InstructionMark im(this);
-  InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
   attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_32bit);
   vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
   emit_int8(0x5C);
@@ -4894,7 +4894,7 @@
 
 void Assembler::vsubss(XMMRegister dst, XMMRegister nds, XMMRegister src) {
   assert(VM_Version::supports_avx(), "");
-  InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
   int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
   emit_int8(0x5C);
   emit_int8((unsigned char)(0xC0 | encode));
@@ -5203,6 +5203,24 @@
   emit_operand(dst, src);
 }
 
+void Assembler::vsqrtps(XMMRegister dst, XMMRegister src, int vector_len) {
+  assert(VM_Version::supports_avx(), "");
+  InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true);
+  int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
+  emit_int8(0x51);
+  emit_int8((unsigned char)(0xC0 | encode));
+}
+
+void Assembler::vsqrtps(XMMRegister dst, Address src, int vector_len) {
+  assert(VM_Version::supports_avx(), "");
+  InstructionMark im(this);
+  InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true);
+  attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_64bit);
+  vex_prefix(src, 0, dst->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
+  emit_int8(0x51);
+  emit_operand(dst, src);
+}
+
 void Assembler::andpd(XMMRegister dst, XMMRegister src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
   InstructionAttr attributes(AVX_128bit, /* rex_w */ !_legacy_mode_dq, /* legacy_mode */ _legacy_mode_dq, /* no_mask_reg */ false, /* uses_vl */ true);
@@ -5377,7 +5395,7 @@
 void Assembler::vphaddw(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
   assert(VM_Version::supports_avx() && (vector_len == 0) ||
          VM_Version::supports_avx2(), "256 bit integer vectors requires AVX2");
-  InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
   int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
   emit_int8(0x01);
   emit_int8((unsigned char)(0xC0 | encode));
@@ -5436,7 +5454,7 @@
 
 void Assembler::phaddw(XMMRegister dst, XMMRegister src) {
   assert(VM_Version::supports_sse3(), "");
-  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
   int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
   emit_int8(0x01);
   emit_int8((unsigned char)(0xC0 | encode));
@@ -6679,7 +6697,7 @@
 
 void Assembler::vzeroupper() {
   if (VM_Version::supports_vzeroupper()) {
-    InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ false, /* uses_vl */ false);
+    InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
     (void)vex_prefix_and_encode(0, 0, 0, VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
     emit_int8(0x77);
   }
@@ -7442,7 +7460,7 @@
 
 void Assembler::shlxl(Register dst, Register src1, Register src2) {
   assert(VM_Version::supports_bmi2(), "");
-  InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
   int encode = vex_prefix_and_encode(dst->encoding(), src2->encoding(), src1->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
   emit_int8((unsigned char)0xF7);
   emit_int8((unsigned char)(0xC0 | encode));
@@ -7450,7 +7468,7 @@
 
 void Assembler::shlxq(Register dst, Register src1, Register src2) {
   assert(VM_Version::supports_bmi2(), "");
-  InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
   int encode = vex_prefix_and_encode(dst->encoding(), src2->encoding(), src1->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
   emit_int8((unsigned char)0xF7);
   emit_int8((unsigned char)(0xC0 | encode));
@@ -7985,7 +8003,7 @@
 
 void Assembler::andnq(Register dst, Register src1, Register src2) {
   assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported");
-  InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
   int encode = vex_prefix_and_encode(dst->encoding(), src1->encoding(), src2->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_38, &attributes);
   emit_int8((unsigned char)0xF2);
   emit_int8((unsigned char)(0xC0 | encode));
@@ -7994,7 +8012,7 @@
 void Assembler::andnq(Register dst, Register src1, Address src2) {
   assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported");
   InstructionMark im(this);
-  InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
   vex_prefix(src2, src1->encoding(), dst->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_38, &attributes);
   emit_int8((unsigned char)0xF2);
   emit_operand(dst, src2);
@@ -8022,7 +8040,7 @@
 
 void Assembler::blsiq(Register dst, Register src) {
   assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported");
-  InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
   int encode = vex_prefix_and_encode(rbx->encoding(), dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_38, &attributes);
   emit_int8((unsigned char)0xF3);
   emit_int8((unsigned char)(0xC0 | encode));
@@ -8031,7 +8049,7 @@
 void Assembler::blsiq(Register dst, Address src) {
   assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported");
   InstructionMark im(this);
-  InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
   vex_prefix(src, dst->encoding(), rbx->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_38, &attributes);
   emit_int8((unsigned char)0xF3);
   emit_operand(rbx, src);
@@ -8039,7 +8057,7 @@
 
 void Assembler::blsmskq(Register dst, Register src) {
   assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported");
-  InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
   int encode = vex_prefix_and_encode(rdx->encoding(), dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_38, &attributes);
   emit_int8((unsigned char)0xF3);
   emit_int8((unsigned char)(0xC0 | encode));
@@ -8048,7 +8066,7 @@
 void Assembler::blsmskq(Register dst, Address src) {
   assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported");
   InstructionMark im(this);
-  InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
   vex_prefix(src, dst->encoding(), rdx->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_38, &attributes);
   emit_int8((unsigned char)0xF3);
   emit_operand(rdx, src);
@@ -8056,7 +8074,7 @@
 
 void Assembler::blsrq(Register dst, Register src) {
   assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported");
-  InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
   int encode = vex_prefix_and_encode(rcx->encoding(), dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_38, &attributes);
   emit_int8((unsigned char)0xF3);
   emit_int8((unsigned char)(0xC0 | encode));
@@ -8065,7 +8083,7 @@
 void Assembler::blsrq(Register dst, Address src) {
   assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported");
   InstructionMark im(this);
-  InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
   vex_prefix(src, dst->encoding(), rcx->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_38, &attributes);
   emit_int8((unsigned char)0xF3);
   emit_operand(rcx, src);
@@ -8504,7 +8522,7 @@
 
 void Assembler::mulxq(Register dst1, Register dst2, Register src) {
   assert(VM_Version::supports_bmi2(), "bit manipulation instructions not supported");
-  InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
   int encode = vex_prefix_and_encode(dst1->encoding(), dst2->encoding(), src->encoding(), VEX_SIMD_F2, VEX_OPCODE_0F_38, &attributes);
   emit_int8((unsigned char)0xF6);
   emit_int8((unsigned char)(0xC0 | encode));
@@ -8667,7 +8685,7 @@
 
 void Assembler::rorxq(Register dst, Register src, int imm8) {
   assert(VM_Version::supports_bmi2(), "bit manipulation instructions not supported");
-  InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
   int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_F2, VEX_OPCODE_0F_3A, &attributes);
   emit_int8((unsigned char)0xF0);
   emit_int8((unsigned char)(0xC0 | encode));
@@ -8676,7 +8694,7 @@
 
 void Assembler::rorxd(Register dst, Register src, int imm8) {
   assert(VM_Version::supports_bmi2(), "bit manipulation instructions not supported");
-  InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
   int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_F2, VEX_OPCODE_0F_3A, &attributes);
   emit_int8((unsigned char)0xF0);
   emit_int8((unsigned char)(0xC0 | encode));
--- a/src/hotspot/cpu/x86/assembler_x86.hpp	Wed Dec 06 15:14:13 2017 -0800
+++ b/src/hotspot/cpu/x86/assembler_x86.hpp	Sat Dec 02 06:51:10 2017 +0100
@@ -1919,9 +1919,11 @@
   void vdivpd(XMMRegister dst, XMMRegister nds, Address src, int vector_len);
   void vdivps(XMMRegister dst, XMMRegister nds, Address src, int vector_len);
 
-  // Sqrt Packed Floating-Point Values - Double precision only
+  // Sqrt Packed Floating-Point Values
   void vsqrtpd(XMMRegister dst, XMMRegister src, int vector_len);
   void vsqrtpd(XMMRegister dst, Address src, int vector_len);
+  void vsqrtps(XMMRegister dst, XMMRegister src, int vector_len);
+  void vsqrtps(XMMRegister dst, Address src, int vector_len);
 
   // Bitwise Logical AND of Packed Floating-Point Values
   void andpd(XMMRegister dst, XMMRegister src);
--- a/src/hotspot/cpu/x86/macroAssembler_x86.cpp	Wed Dec 06 15:14:13 2017 -0800
+++ b/src/hotspot/cpu/x86/macroAssembler_x86.cpp	Sat Dec 02 06:51:10 2017 +0100
@@ -6630,6 +6630,13 @@
   }
   // Clear upper bits of YMM registers to avoid SSE <-> AVX transition penalty.
   vzeroupper();
+  // Reset k1 to 0xffff.
+  if (VM_Version::supports_evex()) {
+    push(rcx);
+    movl(rcx, 0xffff);
+    kmovwl(k1, rcx);
+    pop(rcx);
+  }
 
 #ifndef _LP64
   // Either restore the x87 floating pointer control word after returning
--- a/src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp	Wed Dec 06 15:14:13 2017 -0800
+++ b/src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp	Sat Dec 02 06:51:10 2017 +0100
@@ -3388,26 +3388,29 @@
   // No exception case
   __ bind(noException);
 
-  Label no_adjust, bail;
+  Label no_adjust, bail, no_prefix;
   if (SafepointMechanism::uses_thread_local_poll() && !cause_return) {
     // If our stashed return pc was modified by the runtime we avoid touching it
     __ cmpptr(rbx, Address(rbp, wordSize));
     __ jccb(Assembler::notEqual, no_adjust);
 
-#ifdef ASSERT
     // Verify the correct encoding of the poll we're about to skip.
     // See NativeInstruction::is_safepoint_poll()
     __ cmpb(Address(rbx, 0), NativeTstRegMem::instruction_rex_b_prefix);
-    __ jcc(Assembler::notEqual, bail);
-    __ cmpb(Address(rbx, 1), NativeTstRegMem::instruction_code_memXregl);
+    __ jcc(Assembler::notEqual, no_prefix);
+    __ addptr(rbx, 1);
+    __ bind(no_prefix);
+#ifdef ASSERT
+    __ cmpb(Address(rbx, 0), NativeTstRegMem::instruction_code_memXregl);
     __ jcc(Assembler::notEqual, bail);
     // Mask out the modrm bits
-    __ testb(Address(rbx, 2), NativeTstRegMem::modrm_mask);
+    __ testb(Address(rbx, 1), NativeTstRegMem::modrm_mask);
     // rax encodes to 0, so if the bits are nonzero it's incorrect
     __ jcc(Assembler::notZero, bail);
 #endif
     // Adjust return pc forward to step over the safepoint poll instruction
-    __ addptr(Address(rbp, wordSize), 3);
+    __ addptr(rbx, 2);
+    __ movptr(Address(rbp, wordSize), rbx);
   }
 
   __ bind(no_adjust);
--- a/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp	Wed Dec 06 15:14:13 2017 -0800
+++ b/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp	Sat Dec 02 06:51:10 2017 +0100
@@ -1264,9 +1264,12 @@
           CardTableModRefBS* ct = barrier_set_cast<CardTableModRefBS>(bs);
           assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code");
 
-          Label L_loop;
+          Label L_loop, L_done;
           const Register end = count;
 
+          __ testl(count, count);
+          __ jcc(Assembler::zero, L_done); // zero count - nothing to do
+
           __ leaq(end, Address(start, count, TIMES_OOP, 0));  // end == start+count*oop_size
           __ subptr(end, BytesPerHeapOop); // end - 1 to make inclusive
           __ shrptr(start, CardTableModRefBS::card_shift);
@@ -1280,6 +1283,7 @@
           __ movb(Address(start, count, Address::times_1), 0);
           __ decrement(count);
           __ jcc(Assembler::greaterEqual, L_loop);
+        __ BIND(L_done);
         }
         break;
       default:
--- a/src/hotspot/cpu/x86/vm_version_x86.cpp	Wed Dec 06 15:14:13 2017 -0800
+++ b/src/hotspot/cpu/x86/vm_version_x86.cpp	Sat Dec 02 06:51:10 2017 +0100
@@ -629,18 +629,26 @@
     _features &= ~CPU_SSE;
 
   // first try initial setting and detect what we can support
+  int use_avx_limit = 0;
   if (UseAVX > 0) {
     if (UseAVX > 2 && supports_evex()) {
-      UseAVX = 3;
+      use_avx_limit = 3;
     } else if (UseAVX > 1 && supports_avx2()) {
-      UseAVX = 2;
+      use_avx_limit = 2;
     } else if (UseAVX > 0 && supports_avx()) {
-      UseAVX = 1;
+      use_avx_limit = 1;
     } else {
-      UseAVX = 0;
+      use_avx_limit = 0;
     }
+  }
+  if (FLAG_IS_DEFAULT(UseAVX)) {
+    FLAG_SET_DEFAULT(UseAVX, use_avx_limit);
+  } else if (UseAVX > use_avx_limit) {
+    warning("UseAVX=%d is not supported on this CPU, setting it to UseAVX=%d", (int) UseAVX, use_avx_limit);
+    FLAG_SET_DEFAULT(UseAVX, use_avx_limit);
   } else if (UseAVX < 0) {
-    UseAVX = 0;
+    warning("UseAVX=%d is not valid, setting it to UseAVX=0", (int) UseAVX);
+    FLAG_SET_DEFAULT(UseAVX, 0);
   }
 
   if (UseAVX < 3) {
@@ -710,16 +718,29 @@
   // UseSSE is set to the smaller of what hardware supports and what
   // the command line requires.  I.e., you cannot set UseSSE to 2 on
   // older Pentiums which do not support it.
-  if (UseSSE > 4) UseSSE=4;
-  if (UseSSE < 0) UseSSE=0;
-  if (!supports_sse4_1()) // Drop to 3 if no SSE4 support
-    UseSSE = MIN2((intx)3,UseSSE);
-  if (!supports_sse3()) // Drop to 2 if no SSE3 support
-    UseSSE = MIN2((intx)2,UseSSE);
-  if (!supports_sse2()) // Drop to 1 if no SSE2 support
-    UseSSE = MIN2((intx)1,UseSSE);
-  if (!supports_sse ()) // Drop to 0 if no SSE  support
-    UseSSE = 0;
+  int use_sse_limit = 0;
+  if (UseSSE > 0) {
+    if (UseSSE > 3 && supports_sse4_1()) {
+      use_sse_limit = 4;
+    } else if (UseSSE > 2 && supports_sse3()) {
+      use_sse_limit = 3;
+    } else if (UseSSE > 1 && supports_sse2()) {
+      use_sse_limit = 2;
+    } else if (UseSSE > 0 && supports_sse()) {
+      use_sse_limit = 1;
+    } else {
+      use_sse_limit = 0;
+    }
+  }
+  if (FLAG_IS_DEFAULT(UseSSE)) {
+    FLAG_SET_DEFAULT(UseSSE, use_sse_limit);
+  } else if (UseSSE > use_sse_limit) {
+    warning("UseSSE=%d is not supported on this CPU, setting it to UseSSE=%d", (int) UseSSE, use_sse_limit);
+    FLAG_SET_DEFAULT(UseSSE, use_sse_limit);
+  } else if (UseSSE < 0) {
+    warning("UseSSE=%d is not valid, setting it to UseSSE=0", (int) UseSSE);
+    FLAG_SET_DEFAULT(UseSSE, 0);
+  }
 
   // Use AES instructions if available.
   if (supports_aes()) {
--- a/src/hotspot/cpu/x86/x86.ad	Wed Dec 06 15:14:13 2017 -0800
+++ b/src/hotspot/cpu/x86/x86.ad	Sat Dec 02 06:51:10 2017 +0100
@@ -1252,6 +1252,7 @@
         ret_value = false;
       break;
     case Op_SqrtVD:
+    case Op_SqrtVF:
       if (UseAVX < 1) // enabled for AVX only
         ret_value = false;
       break;
@@ -2580,7 +2581,7 @@
 
 instruct sqrtF_reg(regF dst, regF src) %{
   predicate(UseSSE>=1);
-  match(Set dst (ConvD2F (SqrtD (ConvF2D src))));
+  match(Set dst (SqrtF src));
 
   format %{ "sqrtss  $dst, $src" %}
   ins_cost(150);
@@ -2592,7 +2593,7 @@
 
 instruct sqrtF_mem(regF dst, memory src) %{
   predicate(UseSSE>=1);
-  match(Set dst (ConvD2F (SqrtD (ConvF2D (LoadF src)))));
+  match(Set dst (SqrtF (LoadF src)));
 
   format %{ "sqrtss  $dst, $src" %}
   ins_cost(150);
@@ -2604,7 +2605,8 @@
 
 instruct sqrtF_imm(regF dst, immF con) %{
   predicate(UseSSE>=1);
-  match(Set dst (ConvD2F (SqrtD (ConvF2D con))));
+  match(Set dst (SqrtF con));
+
   format %{ "sqrtss  $dst, [$constantaddress]\t# load from constant table: float=$con" %}
   ins_cost(150);
   ins_encode %{
@@ -8388,7 +8390,7 @@
 
 // --------------------------------- Sqrt --------------------------------------
 
-// Floating point vector sqrt - double precision only
+// Floating point vector sqrt
 instruct vsqrt2D_reg(vecX dst, vecX src) %{
   predicate(UseAVX > 0 && n->as_Vector()->length() == 2);
   match(Set dst (SqrtVD src));
@@ -8455,6 +8457,94 @@
   ins_pipe( pipe_slow );
 %}
 
+instruct vsqrt2F_reg(vecD dst, vecD src) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 2);
+  match(Set dst (SqrtVF src));
+  format %{ "vsqrtps  $dst,$src\t! sqrt packed2F" %}
+  ins_encode %{
+    int vector_len = 0;
+    __ vsqrtps($dst$$XMMRegister, $src$$XMMRegister, vector_len);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsqrt2F_mem(vecD dst, memory mem) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 2);
+  match(Set dst (SqrtVF (LoadVector mem)));
+  format %{ "vsqrtps  $dst,$mem\t! sqrt packed2F" %}
+  ins_encode %{
+    int vector_len = 0;
+    __ vsqrtps($dst$$XMMRegister, $mem$$Address, vector_len);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsqrt4F_reg(vecX dst, vecX src) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 4);
+  match(Set dst (SqrtVF src));
+  format %{ "vsqrtps  $dst,$src\t! sqrt packed4F" %}
+  ins_encode %{
+    int vector_len = 0;
+    __ vsqrtps($dst$$XMMRegister, $src$$XMMRegister, vector_len);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsqrt4F_mem(vecX dst, memory mem) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 4);
+  match(Set dst (SqrtVF (LoadVector mem)));
+  format %{ "vsqrtps  $dst,$mem\t! sqrt packed4F" %}
+  ins_encode %{
+    int vector_len = 0;
+    __ vsqrtps($dst$$XMMRegister, $mem$$Address, vector_len);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsqrt8F_reg(vecY dst, vecY src) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 8);
+  match(Set dst (SqrtVF src));
+  format %{ "vsqrtps  $dst,$src\t! sqrt packed8F" %}
+  ins_encode %{
+    int vector_len = 1;
+    __ vsqrtps($dst$$XMMRegister, $src$$XMMRegister, vector_len);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsqrt8F_mem(vecY dst, memory mem) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 8);
+  match(Set dst (SqrtVF (LoadVector mem)));
+  format %{ "vsqrtps  $dst,$mem\t! sqrt packed8F" %}
+  ins_encode %{
+    int vector_len = 1;
+    __ vsqrtps($dst$$XMMRegister, $mem$$Address, vector_len);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsqrt16F_reg(vecZ dst, vecZ src) %{
+  predicate(UseAVX > 2 && n->as_Vector()->length() == 16);
+  match(Set dst (SqrtVF src));
+  format %{ "vsqrtps  $dst,$src\t! sqrt packed16F" %}
+  ins_encode %{
+    int vector_len = 2;
+    __ vsqrtps($dst$$XMMRegister, $src$$XMMRegister, vector_len);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsqrt16F_mem(vecZ dst, memory mem) %{
+  predicate(UseAVX > 2 && n->as_Vector()->length() == 16);
+  match(Set dst (SqrtVF (LoadVector mem)));
+  format %{ "vsqrtps  $dst,$mem\t! sqrt packed16F" %}
+  ins_encode %{
+    int vector_len = 2;
+    __ vsqrtps($dst$$XMMRegister, $mem$$Address, vector_len);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
 // ------------------------------ LeftShift -----------------------------------
 
 // Shorts/Chars vector left shift
--- a/src/hotspot/os/aix/osThread_aix.cpp	Wed Dec 06 15:14:13 2017 -0800
+++ b/src/hotspot/os/aix/osThread_aix.cpp	Sat Dec 02 06:51:10 2017 +0100
@@ -25,6 +25,7 @@
 
 // no precompiled headers
 
+#include "memory/allocation.inline.hpp"
 #include "runtime/handles.inline.hpp"
 #include "runtime/mutexLocker.hpp"
 #include "runtime/os.hpp"
--- a/src/hotspot/os/aix/os_aix.cpp	Wed Dec 06 15:14:13 2017 -0800
+++ b/src/hotspot/os/aix/os_aix.cpp	Sat Dec 02 06:51:10 2017 +0100
@@ -2490,6 +2490,22 @@
   return false;
 }
 
+char* os::pd_attempt_reserve_memory_at(size_t bytes, char* requested_addr, int file_desc) {
+  assert(file_desc >= 0, "file_desc is not valid");
+  char* result = NULL;
+
+  // Always round to os::vm_page_size(), which may be larger than 4K.
+  bytes = align_up(bytes, os::vm_page_size());
+  result = reserve_mmaped_memory(bytes, requested_addr, 0);
+
+  if (result != NULL) {
+    if (replace_existing_mapping_with_file_mapping(result, bytes, file_desc) == NULL) {
+      vm_exit_during_initialization(err_msg("Error in mapping Java heap at the given filesystem directory"));
+    }
+  }
+  return result;
+}
+
 // Reserve memory at an arbitrary address, only if that area is
 // available (and not reserved for something else).
 char* os::pd_attempt_reserve_memory_at(size_t bytes, char* requested_addr) {
--- a/src/hotspot/os/bsd/osThread_bsd.cpp	Wed Dec 06 15:14:13 2017 -0800
+++ b/src/hotspot/os/bsd/osThread_bsd.cpp	Sat Dec 02 06:51:10 2017 +0100
@@ -23,6 +23,7 @@
  */
 
 // no precompiled headers
+#include "memory/allocation.inline.hpp"
 #include "runtime/mutexLocker.hpp"
 #include "runtime/osThread.hpp"
 
--- a/src/hotspot/os/bsd/os_bsd.cpp	Wed Dec 06 15:14:13 2017 -0800
+++ b/src/hotspot/os/bsd/os_bsd.cpp	Sat Dec 02 06:51:10 2017 +0100
@@ -2350,6 +2350,17 @@
   return UseHugeTLBFS;
 }
 
+char* os::pd_attempt_reserve_memory_at(size_t bytes, char* requested_addr, int file_desc) {
+  assert(file_desc >= 0, "file_desc is not valid");
+  char* result = pd_attempt_reserve_memory_at(bytes, requested_addr);
+  if (result != NULL) {
+    if (replace_existing_mapping_with_file_mapping(result, bytes, file_desc) == NULL) {
+      vm_exit_during_initialization(err_msg("Error in mapping Java heap at the given filesystem directory"));
+    }
+  }
+  return result;
+}
+
 // Reserve memory at an arbitrary address, only if that area is
 // available (and not reserved for something else).
 
--- a/src/hotspot/os/linux/osContainer_linux.cpp	Wed Dec 06 15:14:13 2017 -0800
+++ b/src/hotspot/os/linux/osContainer_linux.cpp	Sat Dec 02 06:51:10 2017 +0100
@@ -323,7 +323,12 @@
     }
   }
 
-  if (mntinfo != NULL) fclose(mntinfo);
+  fclose(mntinfo);
+
+  if (memory == NULL || cpuset == NULL || cpu == NULL || cpuacct == NULL) {
+    log_debug(os, container)("Required cgroup subsystems not found");
+    return;
+  }
 
   /*
    * Read /proc/self/cgroup and map host mount point to
@@ -383,12 +388,7 @@
     }
   }
 
-  if (cgroup != NULL) fclose(cgroup);
-
-  if (memory == NULL || cpuset == NULL || cpu == NULL) {
-    log_debug(os, container)("Required cgroup subsystems not found");
-    return;
-  }
+  fclose(cgroup);
 
   // We need to update the amount of physical memory now that
   // command line arguments have been processed.
--- a/src/hotspot/os/linux/osThread_linux.cpp	Wed Dec 06 15:14:13 2017 -0800
+++ b/src/hotspot/os/linux/osThread_linux.cpp	Sat Dec 02 06:51:10 2017 +0100
@@ -23,6 +23,7 @@
  */
 
 // no precompiled headers
+#include "memory/allocation.inline.hpp"
 #include "runtime/mutex.hpp"
 #include "runtime/osThread.hpp"
 
--- a/src/hotspot/os/linux/os_linux.cpp	Wed Dec 06 15:14:13 2017 -0800
+++ b/src/hotspot/os/linux/os_linux.cpp	Sat Dec 02 06:51:10 2017 +0100
@@ -59,6 +59,7 @@
 #include "runtime/stubRoutines.hpp"
 #include "runtime/thread.inline.hpp"
 #include "runtime/threadCritical.hpp"
+#include "runtime/threadSMR.hpp"
 #include "runtime/timer.hpp"
 #include "semaphore_posix.hpp"
 #include "services/attachListener.hpp"
@@ -129,6 +130,7 @@
 #define ALL_64_BITS CONST64(0xFFFFFFFFFFFFFFFF)
 
 #define LARGEPAGES_BIT (1 << 6)
+#define DAX_SHARED_BIT (1 << 8)
 ////////////////////////////////////////////////////////////////////////////////
 // global variables
 julong os::Linux::_physical_memory = 0;
@@ -1646,7 +1648,10 @@
         //
         // Dynamic loader will make all stacks executable after
         // this function returns, and will not do that again.
-        assert(Threads::first() == NULL, "no Java threads should exist yet.");
+#ifdef ASSERT
+        ThreadsListHandle tlh;
+        assert(tlh.length() == 0, "no Java threads should exist yet.");
+#endif
       } else {
         warning("You have loaded library %s which might have disabled stack guard. "
                 "The VM will try to fix the stack guard now.\n"
@@ -1874,16 +1879,13 @@
   // may have been queued at the same time.
 
   if (!_stack_is_executable) {
-    JavaThread *jt = Threads::first();
-
-    while (jt) {
+    for (JavaThreadIteratorWithHandle jtiwh; JavaThread *jt = jtiwh.next(); ) {
       if (!jt->stack_guard_zone_unused() &&     // Stack not yet fully initialized
           jt->stack_guards_enabled()) {         // No pending stack overflow exceptions
         if (!os::guard_memory((char *)jt->stack_end(), jt->stack_guard_zone_size())) {
           warning("Attempt to reguard stack yellow zone failed.");
         }
       }
-      jt = jt->next();
     }
   }
 
@@ -3369,10 +3371,13 @@
 //           effective only if the bit 2 is cleared)
 // - (bit 5) hugetlb private memory
 // - (bit 6) hugetlb shared memory
+// - (bit 7) dax private memory
+// - (bit 8) dax shared memory
 //
-static void set_coredump_filter(void) {
+static void set_coredump_filter(bool largepages, bool dax_shared) {
   FILE *f;
   long cdm;
+  bool filter_changed = false;
 
   if ((f = fopen("/proc/self/coredump_filter", "r+")) == NULL) {
     return;
@@ -3385,8 +3390,15 @@
 
   rewind(f);
 
-  if ((cdm & LARGEPAGES_BIT) == 0) {
+  if (largepages && (cdm & LARGEPAGES_BIT) == 0) {
     cdm |= LARGEPAGES_BIT;
+    filter_changed = true;
+  }
+  if (dax_shared && (cdm & DAX_SHARED_BIT) == 0) {
+    cdm |= DAX_SHARED_BIT;
+    filter_changed = true;
+  }
+  if (filter_changed) {
     fprintf(f, "%#lx", cdm);
   }
 
@@ -3525,7 +3537,7 @@
   size_t large_page_size = Linux::setup_large_page_size();
   UseLargePages          = Linux::setup_large_page_type(large_page_size);
 
-  set_coredump_filter();
+  set_coredump_filter(true /*largepages*/, false /*dax_shared*/);
 }
 
 #ifndef SHM_HUGETLB
@@ -3896,6 +3908,17 @@
   return UseTransparentHugePages || UseHugeTLBFS;
 }
 
+char* os::pd_attempt_reserve_memory_at(size_t bytes, char* requested_addr, int file_desc) {
+  assert(file_desc >= 0, "file_desc is not valid");
+  char* result = pd_attempt_reserve_memory_at(bytes, requested_addr);
+  if (result != NULL) {
+    if (replace_existing_mapping_with_file_mapping(result, bytes, file_desc) == NULL) {
+      vm_exit_during_initialization(err_msg("Error in mapping Java heap at the given filesystem directory"));
+    }
+  }
+  return result;
+}
+
 // Reserve memory at an arbitrary address, only if that area is
 // available (and not reserved for something else).
 
@@ -4947,25 +4970,20 @@
         UseNUMA = false;
       }
     }
-    // With SHM and HugeTLBFS large pages we cannot uncommit a page, so there's no way
-    // we can make the adaptive lgrp chunk resizing work. If the user specified
-    // both UseNUMA and UseLargePages (or UseSHM/UseHugeTLBFS) on the command line - warn and
-    // disable adaptive resizing.
-    if (UseNUMA && UseLargePages && !can_commit_large_page_memory()) {
-      if (FLAG_IS_DEFAULT(UseNUMA)) {
-        UseNUMA = false;
-      } else {
-        if (FLAG_IS_DEFAULT(UseLargePages) &&
-            FLAG_IS_DEFAULT(UseSHM) &&
-            FLAG_IS_DEFAULT(UseHugeTLBFS)) {
-          UseLargePages = false;
-        } else if (UseAdaptiveSizePolicy || UseAdaptiveNUMAChunkSizing) {
-          warning("UseNUMA is not fully compatible with SHM/HugeTLBFS large pages, disabling adaptive resizing (-XX:-UseAdaptiveSizePolicy -XX:-UseAdaptiveNUMAChunkSizing)");
-          UseAdaptiveSizePolicy = false;
-          UseAdaptiveNUMAChunkSizing = false;
-        }
+
+    if (UseParallelGC && UseNUMA && UseLargePages && !can_commit_large_page_memory()) {
+      // With SHM and HugeTLBFS large pages we cannot uncommit a page, so there's no way
+      // we can make the adaptive lgrp chunk resizing work. If the user specified both
+      // UseNUMA and UseLargePages (or UseSHM/UseHugeTLBFS) on the command line - warn
+      // and disable adaptive resizing.
+      if (UseAdaptiveSizePolicy || UseAdaptiveNUMAChunkSizing) {
+        warning("UseNUMA is not fully compatible with SHM/HugeTLBFS large pages, "
+                "disabling adaptive resizing (-XX:-UseAdaptiveSizePolicy -XX:-UseAdaptiveNUMAChunkSizing)");
+        UseAdaptiveSizePolicy = false;
+        UseAdaptiveNUMAChunkSizing = false;
       }
     }
+
     if (!UseNUMA && ForceNUMA) {
       UseNUMA = true;
     }
@@ -5012,6 +5030,9 @@
   // initialize thread priority policy
   prio_init();
 
+  if (!FLAG_IS_DEFAULT(AllocateHeapAt)) {
+    set_coredump_filter(false /*largepages*/, true /*dax_shared*/);
+  }
   return JNI_OK;
 }
 
--- a/src/hotspot/os/posix/os_posix.cpp	Wed Dec 06 15:14:13 2017 -0800
+++ b/src/hotspot/os/posix/os_posix.cpp	Sat Dec 02 06:51:10 2017 +0100
@@ -40,6 +40,7 @@
 #include <pthread.h>
 #include <semaphore.h>
 #include <signal.h>
+#include <sys/mman.h>
 #include <sys/resource.h>
 #include <sys/utsname.h>
 #include <time.h>
@@ -52,6 +53,20 @@
 #endif
 #define IS_VALID_PID(p) (p > 0 && p < MAX_PID)
 
+#ifndef MAP_ANONYMOUS
+  #define MAP_ANONYMOUS MAP_ANON
+#endif
+
+#define check_with_errno(check_type, cond, msg)                             \
+  do {                                                                      \
+    int err = errno;                                                        \
+    check_type(cond, "%s; error='%s' (errno=%s)", msg, os::strerror(err),   \
+               os::errno_name(err));                                        \
+} while (false)
+
+#define assert_with_errno(cond, msg)    check_with_errno(assert, cond, msg)
+#define guarantee_with_errno(cond, msg) check_with_errno(guarantee, cond, msg)
+
 // Check core dump limit and report possible place where core can be found
 void os::check_dump_limit(char* buffer, size_t bufferSize) {
   if (!FLAG_IS_DEFAULT(CreateCoredumpOnCrash) && !CreateCoredumpOnCrash) {
@@ -145,10 +160,124 @@
   return;
 }
 
+int os::create_file_for_heap(const char* dir) {
+
+  const char name_template[] = "/jvmheap.XXXXXX";
+
+  char *fullname = (char*)os::malloc((strlen(dir) + strlen(name_template) + 1), mtInternal);
+  if (fullname == NULL) {
+    vm_exit_during_initialization(err_msg("Malloc failed during creation of backing file for heap (%s)", os::strerror(errno)));
+    return -1;
+  }
+  (void)strncpy(fullname, dir, strlen(dir)+1);
+  (void)strncat(fullname, name_template, strlen(name_template));
+
+  os::native_path(fullname);
+
+  sigset_t set, oldset;
+  int ret = sigfillset(&set);
+  assert_with_errno(ret == 0, "sigfillset returned error");
+
+  // set the file creation mask.
+  mode_t file_mode = S_IRUSR | S_IWUSR;
+
+  // create a new file.
+  int fd = mkstemp(fullname);
+
+  if (fd < 0) {
+    warning("Could not create file for heap with template %s", fullname);
+    os::free(fullname);
+    return -1;
+  }
+
+  // delete the name from the filesystem. When 'fd' is closed, the file (and space) will be deleted.
+  ret = unlink(fullname);
+  assert_with_errno(ret == 0, "unlink returned error");
+
+  os::free(fullname);
+  return fd;
+}
+
+static char* reserve_mmapped_memory(size_t bytes, char* requested_addr) {
+  char * addr;
+  int flags = MAP_PRIVATE NOT_AIX( | MAP_NORESERVE ) | MAP_ANONYMOUS;
+  if (requested_addr != NULL) {
+    assert((uintptr_t)requested_addr % os::vm_page_size() == 0, "Requested address should be aligned to OS page size");
+    flags |= MAP_FIXED;
+  }
+
+  // Map reserved/uncommitted pages PROT_NONE so we fail early if we
+  // touch an uncommitted page. Otherwise, the read/write might
+  // succeed if we have enough swap space to back the physical page.
+  addr = (char*)::mmap(requested_addr, bytes, PROT_NONE,
+                       flags, -1, 0);
+
+  if (addr != MAP_FAILED) {
+    MemTracker::record_virtual_memory_reserve((address)addr, bytes, CALLER_PC);
+    return addr;
+  }
+  return NULL;
+}
+
+static int util_posix_fallocate(int fd, off_t offset, off_t len) {
+#ifdef __APPLE__
+  fstore_t store = { F_ALLOCATECONTIG, F_PEOFPOSMODE, 0, len };
+  // First we try to get a continuous chunk of disk space
+  int ret = fcntl(fd, F_PREALLOCATE, &store);
+  if (ret == -1) {
+    // Maybe we are too fragmented, try to allocate non-continuous range
+    store.fst_flags = F_ALLOCATEALL;
+    ret = fcntl(fd, F_PREALLOCATE, &store);
+  }
+  if(ret != -1) {
+    return ftruncate(fd, len);
+  }
+  return -1;
+#else
+  return posix_fallocate(fd, offset, len);
+#endif
+}
+
+// Map the given address range to the provided file descriptor.
+char* os::map_memory_to_file(char* base, size_t size, int fd) {
+  assert(fd != -1, "File descriptor is not valid");
+
+  // allocate space for the file
+  if (util_posix_fallocate(fd, 0, (off_t)size) != 0) {
+    vm_exit_during_initialization(err_msg("Error in mapping Java heap at the given filesystem directory."));
+    return NULL;
+  }
+
+  int prot = PROT_READ | PROT_WRITE;
+  int flags = MAP_SHARED;
+  if (base != NULL) {
+    flags |= MAP_FIXED;
+  }
+  char* addr = (char*)mmap(base, size, prot, flags, fd, 0);
+
+  if (addr == MAP_FAILED) {
+    return NULL;
+  }
+  if (base != NULL && addr != base) {
+    if (!os::release_memory(addr, size)) {
+      warning("Could not release memory on unsuccessful file mapping");
+     }
+    return NULL;
+  }
+  return addr;
+}
+
+char* os::replace_existing_mapping_with_file_mapping(char* base, size_t size, int fd) {
+  assert(fd != -1, "File descriptor is not valid");
+  assert(base != NULL, "Base cannot be NULL");
+
+  return map_memory_to_file(base, size, fd);
+}
+
 // Multiple threads can race in this code, and can remap over each other with MAP_FIXED,
 // so on posix, unmap the section at the start and at the end of the chunk that we mapped
 // rather than unmapping and remapping the whole chunk to get requested alignment.
-char* os::reserve_memory_aligned(size_t size, size_t alignment) {
+char* os::reserve_memory_aligned(size_t size, size_t alignment, int file_desc) {
   assert((alignment & (os::vm_allocation_granularity() - 1)) == 0,
       "Alignment must be a multiple of allocation granularity (page size)");
   assert((size & (alignment -1)) == 0, "size must be 'alignment' aligned");
@@ -156,7 +285,20 @@
   size_t extra_size = size + alignment;
   assert(extra_size >= size, "overflow, size is too large to allow alignment");
 
-  char* extra_base = os::reserve_memory(extra_size, NULL, alignment);
+  char* extra_base;
+  if (file_desc != -1) {
+    // For file mapping, we do not call os:reserve_memory(extra_size, NULL, alignment, file_desc) because
+    // we need to deal with shrinking of the file space later when we release extra memory after alignment.
+    // We also cannot called os:reserve_memory() with file_desc set to -1 because on aix we might get SHM memory.
+    // So here to call a helper function while reserve memory for us. After we have a aligned base,
+    // we will replace anonymous mapping with file mapping.
+    extra_base = reserve_mmapped_memory(extra_size, NULL);
+    if (extra_base != NULL) {
+      MemTracker::record_virtual_memory_reserve((address)extra_base, extra_size, CALLER_PC);
+    }
+  } else {
+    extra_base = os::reserve_memory(extra_size, NULL, alignment);
+  }
 
   if (extra_base == NULL) {
     return NULL;
@@ -183,6 +325,13 @@
       os::release_memory(extra_base + begin_offset + size, end_offset);
   }
 
+  if (file_desc != -1) {
+    // After we have an aligned address, we can replace anonymous mapping with file mapping
+    if (replace_existing_mapping_with_file_mapping(aligned_base, size, file_desc) == NULL) {
+      vm_exit_during_initialization(err_msg("Error in mapping Java heap at the given filesystem directory"));
+    }
+    MemTracker::record_virtual_memory_commit((address)aligned_base, size, CALLER_PC);
+  }
   return aligned_base;
 }
 
@@ -478,8 +627,7 @@
 // interrupt support
 
 void os::interrupt(Thread* thread) {
-  assert(Thread::current() == thread || Threads_lock->owned_by_self(),
-    "possibility of dangling Thread pointer");
+  debug_only(Thread::check_for_dangling_thread_pointer(thread);)
 
   OSThread* osthread = thread->osthread();
 
@@ -499,12 +647,10 @@
 
   ParkEvent * ev = thread->_ParkEvent ;
   if (ev != NULL) ev->unpark() ;
-
 }
 
 bool os::is_interrupted(Thread* thread, bool clear_interrupted) {
-  assert(Thread::current() == thread || Threads_lock->owned_by_self(),
-    "possibility of dangling Thread pointer");
+  debug_only(Thread::check_for_dangling_thread_pointer(thread);)
 
   OSThread* osthread = thread->osthread();
 
@@ -1351,16 +1497,6 @@
   }
 }
 
-#define check_with_errno(check_type, cond, msg)                             \
-  do {                                                                      \
-    int err = errno;                                                        \
-    check_type(cond, "%s; error='%s' (errno=%s)", msg, os::strerror(err),   \
-               os::errno_name(err));                                        \
-} while (false)
-
-#define assert_with_errno(cond, msg)    check_with_errno(assert, cond, msg)
-#define guarantee_with_errno(cond, msg) check_with_errno(guarantee, cond, msg)
-
 // POSIX unamed semaphores are not supported on OS X.
 #ifndef __APPLE__
 
--- a/src/hotspot/os/solaris/os_solaris.cpp	Wed Dec 06 15:14:13 2017 -0800
+++ b/src/hotspot/os/solaris/os_solaris.cpp	Sat Dec 02 06:51:10 2017 +0100
@@ -2585,6 +2585,17 @@
   return addr;
 }
 
+char* os::pd_attempt_reserve_memory_at(size_t bytes, char* requested_addr, int file_desc) {
+  assert(file_desc >= 0, "file_desc is not valid");
+  char* result = pd_attempt_reserve_memory_at(bytes, requested_addr);
+  if (result != NULL) {
+    if (replace_existing_mapping_with_file_mapping(result, bytes, file_desc) == NULL) {
+      vm_exit_during_initialization(err_msg("Error in mapping Java heap at the given filesystem directory"));
+    }
+  }
+  return result;
+}
+
 // Reserve memory at an arbitrary address, only if that area is
 // available (and not reserved for something else).
 
--- a/src/hotspot/os/windows/os_windows.cpp	Wed Dec 06 15:14:13 2017 -0800
+++ b/src/hotspot/os/windows/os_windows.cpp	Sat Dec 02 06:51:10 2017 +0100
@@ -2904,6 +2904,75 @@
   UseLargePages = success;
 }
 
+int os::create_file_for_heap(const char* dir) {
+
+  const char name_template[] = "/jvmheap.XXXXXX";
+  char *fullname = (char*)os::malloc((strlen(dir) + strlen(name_template) + 1), mtInternal);
+  if (fullname == NULL) {
+    vm_exit_during_initialization(err_msg("Malloc failed during creation of backing file for heap (%s)", os::strerror(errno)));
+    return -1;
+  }
+
+  (void)strncpy(fullname, dir, strlen(dir)+1);
+  (void)strncat(fullname, name_template, strlen(name_template));
+
+  os::native_path(fullname);
+
+  char *path = _mktemp(fullname);
+  if (path == NULL) {
+    warning("_mktemp could not create file name from template %s (%s)", fullname, os::strerror(errno));
+    os::free(fullname);
+    return -1;
+  }
+
+  int fd = _open(path, O_RDWR | O_CREAT | O_TEMPORARY | O_EXCL, S_IWRITE | S_IREAD);
+
+  os::free(fullname);
+  if (fd < 0) {
+    warning("Problem opening file for heap (%s)", os::strerror(errno));
+    return -1;
+  }
+  return fd;
+}
+
+// If 'base' is not NULL, function will return NULL if it cannot get 'base'
+char* os::map_memory_to_file(char* base, size_t size, int fd) {
+  assert(fd != -1, "File descriptor is not valid");
+
+  HANDLE fh = (HANDLE)_get_osfhandle(fd);
+#ifdef _LP64
+  HANDLE fileMapping = CreateFileMapping(fh, NULL, PAGE_READWRITE,
+    (DWORD)(size >> 32), (DWORD)(size & 0xFFFFFFFF), NULL);
+#else
+  HANDLE fileMapping = CreateFileMapping(fh, NULL, PAGE_READWRITE,
+    0, (DWORD)size, NULL);
+#endif
+  if (fileMapping == NULL) {
+    if (GetLastError() == ERROR_DISK_FULL) {
+      vm_exit_during_initialization(err_msg("Could not allocate sufficient disk space for Java heap"));
+    }
+    else {
+      vm_exit_during_initialization(err_msg("Error in mapping Java heap at the given filesystem directory"));
+    }
+
+    return NULL;
+  }
+
+  LPVOID addr = MapViewOfFileEx(fileMapping, FILE_MAP_WRITE, 0, 0, size, base);
+
+  CloseHandle(fileMapping);
+
+  return (char*)addr;
+}
+
+char* os::replace_existing_mapping_with_file_mapping(char* base, size_t size, int fd) {
+  assert(fd != -1, "File descriptor is not valid");
+  assert(base != NULL, "Base address cannot be NULL");
+
+  release_memory(base, size);
+  return map_memory_to_file(base, size, fd);
+}
+
 // On win32, one cannot release just a part of reserved memory, it's an
 // all or nothing deal.  When we split a reservation, we must break the
 // reservation into two reservations.
@@ -2923,7 +2992,7 @@
 // Multiple threads can race in this code but it's not possible to unmap small sections of
 // virtual space to get requested alignment, like posix-like os's.
 // Windows prevents multiple thread from remapping over each other so this loop is thread-safe.
-char* os::reserve_memory_aligned(size_t size, size_t alignment) {
+char* os::reserve_memory_aligned(size_t size, size_t alignment, int file_desc) {
   assert((alignment & (os::vm_allocation_granularity() - 1)) == 0,
          "Alignment must be a multiple of allocation granularity (page size)");
   assert((size & (alignment -1)) == 0, "size must be 'alignment' aligned");
@@ -2934,16 +3003,20 @@
   char* aligned_base = NULL;
 
   do {
-    char* extra_base = os::reserve_memory(extra_size, NULL, alignment);
+    char* extra_base = os::reserve_memory(extra_size, NULL, alignment, file_desc);
     if (extra_base == NULL) {
       return NULL;
     }
     // Do manual alignment
     aligned_base = align_up(extra_base, alignment);
 
-    os::release_memory(extra_base, extra_size);
-
-    aligned_base = os::reserve_memory(size, aligned_base);
+    if (file_desc != -1) {
+      os::unmap_memory(extra_base, extra_size);
+    } else {
+      os::release_memory(extra_base, extra_size);
+    }
+
+    aligned_base = os::reserve_memory(size, aligned_base, 0, file_desc);
 
   } while (aligned_base == NULL);
 
@@ -2989,6 +3062,11 @@
   return reserve_memory(bytes, requested_addr);
 }
 
+char* os::pd_attempt_reserve_memory_at(size_t bytes, char* requested_addr, int file_desc) {
+  assert(file_desc >= 0, "file_desc is not valid");
+  return map_memory_to_file(requested_addr, bytes, file_desc);
+}
+
 size_t os::large_page_size() {
   return _large_page_size;
 }
@@ -3490,9 +3568,7 @@
 void os::hint_no_preempt() {}
 
 void os::interrupt(Thread* thread) {
-  assert(!thread->is_Java_thread() || Thread::current() == thread ||
-         Threads_lock->owned_by_self(),
-         "possibility of dangling Thread pointer");
+  debug_only(Thread::check_for_dangling_thread_pointer(thread);)
 
   OSThread* osthread = thread->osthread();
   osthread->set_interrupted(true);
@@ -3513,8 +3589,7 @@
 
 
 bool os::is_interrupted(Thread* thread, bool clear_interrupted) {
-  assert(!thread->is_Java_thread() || Thread::current() == thread || Threads_lock->owned_by_self(),
-         "possibility of dangling Thread pointer");
+  debug_only(Thread::check_for_dangling_thread_pointer(thread);)
 
   OSThread* osthread = thread->osthread();
   // There is no synchronization between the setting of the interrupt
--- a/src/hotspot/os_cpu/linux_zero/atomic_linux_zero.hpp	Wed Dec 06 15:14:13 2017 -0800
+++ b/src/hotspot/os_cpu/linux_zero/atomic_linux_zero.hpp	Sat Dec 02 06:51:10 2017 +0100
@@ -30,74 +30,6 @@
 
 // Implementation of class atomic
 
-#ifdef M68K
-
-/*
- * __m68k_cmpxchg
- *
- * Atomically store newval in *ptr if *ptr is equal to oldval for user space.
- * Returns newval on success and oldval if no exchange happened.
- * This implementation is processor specific and works on
- * 68020 68030 68040 and 68060.
- *
- * It will not work on ColdFire, 68000 and 68010 since they lack the CAS
- * instruction.
- * Using a kernelhelper would be better for arch complete implementation.
- *
- */
-
-static inline int __m68k_cmpxchg(int oldval, int newval, volatile int *ptr) {
-  int ret;
-  __asm __volatile ("cas%.l %0,%2,%1"
-                   : "=d" (ret), "+m" (*(ptr))
-                   : "d" (newval), "0" (oldval));
-  return ret;
-}
-
-/* Perform an atomic compare and swap: if the current value of `*PTR'
-   is OLDVAL, then write NEWVAL into `*PTR'.  Return the contents of
-   `*PTR' before the operation.*/
-static inline int m68k_compare_and_swap(int newval,
-                                        volatile int *ptr,
-                                        int oldval) {
-  for (;;) {
-      int prev = *ptr;
-      if (prev != oldval)
-        return prev;
-
-      if (__m68k_cmpxchg (prev, newval, ptr) == newval)
-        // Success.
-        return prev;
-
-      // We failed even though prev == oldval.  Try again.
-    }
-}
-
-/* Atomically add an int to memory.  */
-static inline int m68k_add_and_fetch(int add_value, volatile int *ptr) {
-  for (;;) {
-      // Loop until success.
-
-      int prev = *ptr;
-
-      if (__m68k_cmpxchg (prev, prev + add_value, ptr) == prev + add_value)
-        return prev + add_value;
-    }
-}
-
-/* Atomically write VALUE into `*PTR' and returns the previous
-   contents of `*PTR'.  */
-static inline int m68k_lock_test_and_set(int newval, volatile int *ptr) {
-  for (;;) {
-      // Loop until success.
-      int prev = *ptr;
-
-      if (__m68k_cmpxchg (prev, newval, ptr) == prev)
-        return prev;
-    }
-}
-#endif // M68K
-
 #ifdef ARM
 
 /*
@@ -176,11 +108,7 @@
 #ifdef ARM
   return add_using_helper<int>(arm_add_and_fetch, add_value, dest);
 #else
-#ifdef M68K
-  return add_using_helper<int>(m68k_add_and_fetch, add_value, dest);
-#else
   return __sync_add_and_fetch(dest, add_value);
-#endif // M68K
 #endif // ARM
 }
 
@@ -201,9 +129,6 @@
 #ifdef ARM
   return xchg_using_helper<int>(arm_lock_test_and_set, exchange_value, dest);
 #else
-#ifdef M68K
-  return xchg_using_helper<int>(m68k_lock_test_and_set, exchange_value, dest);
-#else
   // __sync_lock_test_and_set is a bizarrely named atomic exchange
   // operation.  Note that some platforms only support this with the
   // limitation that the only valid value to store is the immediate
@@ -215,7 +140,6 @@
   // barrier.
   __sync_synchronize();
   return result;
-#endif // M68K
 #endif // ARM
 }
 
@@ -243,11 +167,7 @@
 #ifdef ARM
   return cmpxchg_using_helper<int>(arm_compare_and_swap, exchange_value, dest, compare_value);
 #else
-#ifdef M68K
-  return cmpxchg_using_helper<int>(m68k_compare_and_swap, exchange_value, dest, compare_value);
-#else
   return __sync_val_compare_and_swap(dest, compare_value, exchange_value);
-#endif // M68K
 #endif // ARM
 }
 
--- a/src/hotspot/os_cpu/linux_zero/os_linux_zero.hpp	Wed Dec 06 15:14:13 2017 -0800
+++ b/src/hotspot/os_cpu/linux_zero/os_linux_zero.hpp	Sat Dec 02 06:51:10 2017 +0100
@@ -36,12 +36,18 @@
 
   // Atomically copy 64 bits of data
   static void atomic_copy64(const volatile void *src, volatile void *dst) {
-#if defined(PPC32)
+#if defined(PPC32) && !defined(__SPE__)
     double tmp;
     asm volatile ("lfd  %0, %2\n"
                   "stfd %0, %1\n"
                   : "=&f"(tmp), "=Q"(*(volatile double*)dst)
                   : "Q"(*(volatile double*)src));
+#elif defined(PPC32) && defined(__SPE__)
+    long tmp;
+    asm volatile ("evldd  %0, %2\n"
+                  "evstdd %0, %1\n"
+                  : "=&r"(tmp), "=Q"(*(volatile long*)dst)
+                  : "Q"(*(volatile long*)src));
 #elif defined(S390) && !defined(_LP64)
     double tmp;
     asm volatile ("ld  %0, 0(%1)\n"
--- a/src/hotspot/share/adlc/formssel.cpp	Wed Dec 06 15:14:13 2017 -0800
+++ b/src/hotspot/share/adlc/formssel.cpp	Sat Dec 02 06:51:10 2017 +0100
@@ -4034,6 +4034,7 @@
         strcmp(opType,"ModF")==0 ||
         strcmp(opType,"ModI")==0 ||
         strcmp(opType,"SqrtD")==0 ||
+        strcmp(opType,"SqrtF")==0 ||
         strcmp(opType,"TanD")==0 ||
         strcmp(opType,"ConvD2F")==0 ||
         strcmp(opType,"ConvD2I")==0 ||
@@ -4167,7 +4168,7 @@
     "DivVF","DivVD",
     "AbsVF","AbsVD",
     "NegVF","NegVD",
-    "SqrtVD",
+    "SqrtVD","SqrtVF",
     "AndV" ,"XorV" ,"OrV",
     "AddReductionVI", "AddReductionVL",
     "AddReductionVF", "AddReductionVD",
--- a/src/hotspot/share/aot/aotCodeHeap.cpp	Wed Dec 06 15:14:13 2017 -0800
+++ b/src/hotspot/share/aot/aotCodeHeap.cpp	Sat Dec 02 06:51:10 2017 +0100
@@ -167,6 +167,7 @@
   verify_flag(_config->_compactFields, CompactFields, "CompactFields");
   verify_flag(_config->_enableContended, EnableContended, "EnableContended");
   verify_flag(_config->_restrictContended, RestrictContended, "RestrictContended");
+  verify_flag(_config->_threadLocalHandshakes, ThreadLocalHandshakes, "ThreadLocalHandshakes");
 
   if (!TieredCompilation && _config->_tieredAOT) {
     handle_config_error("Shared file %s error: Expected to run with tiered compilation on", _name);
--- a/src/hotspot/share/aot/aotCodeHeap.hpp	Wed Dec 06 15:14:13 2017 -0800
+++ b/src/hotspot/share/aot/aotCodeHeap.hpp	Sat Dec 02 06:51:10 2017 +0100
@@ -92,7 +92,7 @@
 } AOTHeader;
 
 typedef struct {
-  enum { CONFIG_SIZE = 7 * jintSize + 11 };
+  enum { CONFIG_SIZE = 7 * jintSize + 12 };
   // 7 int values
   int _config_size;
   int _narrowOopShift;
@@ -101,7 +101,7 @@
   int _fieldsAllocationStyle;
   int _objectAlignment;
   int _codeSegmentSize;
-  // byte[11] array map to boolean values here
+  // byte[12] array map to boolean values here
   bool _debug_VM;
   bool _useCompressedOops;
   bool _useCompressedClassPointers;
@@ -113,6 +113,7 @@
   bool _enableContended;
   bool _restrictContended;
   bool _omitAssertions;
+  bool _threadLocalHandshakes;
 } AOTConfiguration;
 
 class AOTLib : public CHeapObj<mtCode> {
--- a/src/hotspot/share/aot/aotLoader.cpp	Wed Dec 06 15:14:13 2017 -0800
+++ b/src/hotspot/share/aot/aotLoader.cpp	Sat Dec 02 06:51:10 2017 +0100
@@ -146,15 +146,6 @@
       return;
     }
 
-    const char* home = Arguments::get_java_home();
-    const char* file_separator = os::file_separator();
-
-    for (int i = 0; i < (int) (sizeof(modules) / sizeof(const char*)); i++) {
-      char library[JVM_MAXPATHLEN];
-      jio_snprintf(library, sizeof(library), "%s%slib%slib%s%s%s%s", home, file_separator, file_separator, modules[i], UseCompressedOops ? "-coop" : "", UseG1GC ? "" : "-nong1", os::dll_file_extension());
-      load_library(library, false);
-    }
-
     // Scan the AOTLibrary option.
     if (AOTLibrary != NULL) {
       const int len = (int)strlen(AOTLibrary);
@@ -172,6 +163,16 @@
         }
       }
     }
+
+    // Load well-know AOT libraries from Java installation directory.
+    const char* home = Arguments::get_java_home();
+    const char* file_separator = os::file_separator();
+
+    for (int i = 0; i < (int) (sizeof(modules) / sizeof(const char*)); i++) {
+      char library[JVM_MAXPATHLEN];
+      jio_snprintf(library, sizeof(library), "%s%slib%slib%s%s%s%s", home, file_separator, file_separator, modules[i], UseCompressedOops ? "-coop" : "", UseG1GC ? "" : "-nong1", os::dll_file_extension());
+      load_library(library, false);
+    }
   }
 }
 
@@ -239,6 +240,21 @@
 }
 
 void AOTLoader::load_library(const char* name, bool exit_on_error) {
+  // Skip library if a library with the same name is already loaded.
+  const int file_separator = *os::file_separator();
+  const char* start = strrchr(name, file_separator);
+  const char* new_name = (start == NULL) ? name : (start + 1);
+  FOR_ALL_AOT_LIBRARIES(lib) {
+    const char* lib_name = (*lib)->name();
+    start = strrchr(lib_name, file_separator);
+    const char* old_name = (start == NULL) ? lib_name : (start + 1);
+    if (strcmp(old_name, new_name) == 0) {
+      if (PrintAOT) {
+        warning("AOT library %s is already loaded as %s.", name, lib_name);
+      }
+      return;
+    }
+  }
   char ebuf[1024];
   void* handle = os::dll_load(name, ebuf, sizeof ebuf);
   if (handle == NULL) {
--- a/src/hotspot/share/c1/c1_LIR.hpp	Wed Dec 06 15:14:13 2017 -0800
+++ b/src/hotspot/share/c1/c1_LIR.hpp	Sat Dec 02 06:51:10 2017 +0100
@@ -196,8 +196,8 @@
   //     data       opr-type opr-kind
   // +--------------+-------+-------+
   // [max...........|7 6 5 4|3 2 1 0]
-  //                             ^
-  //                    is_pointer bit
+  //                               ^
+  //                         is_pointer bit
   //
   // lowest bit cleared, means it is a structure pointer
   // we need  4 bits to represent types
--- a/src/hotspot/share/classfile/classListParser.cpp	Wed Dec 06 15:14:13 2017 -0800
+++ b/src/hotspot/share/classfile/classListParser.cpp	Sat Dec 02 06:51:10 2017 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, 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
@@ -23,13 +23,32 @@
  */
 
 #include "precompiled.hpp"
+#include "jvm.h"
+#include "jimage.hpp"
 #include "classfile/classListParser.hpp"
-#include "runtime/os.hpp"
-#include "runtime/java.hpp"
+#include "classfile/classLoaderExt.hpp"
+#include "classfile/sharedClassUtil.hpp"
+#include "classfile/symbolTable.hpp"
+#include "classfile/systemDictionary.hpp"
+#include "classfile/systemDictionaryShared.hpp"
+#include "memory/metaspaceShared.hpp"
+#include "memory/resourceArea.hpp"
+#include "runtime/fieldType.hpp"
+#include "runtime/javaCalls.hpp"
+#include "utilities/defaultStream.hpp"
+#include "utilities/hashtable.inline.hpp"
+#include "utilities/macros.hpp"
+
+ClassListParser* ClassListParser::_instance = NULL;
 
 ClassListParser::ClassListParser(const char* file) {
+  assert(_instance == NULL, "must be singleton");
+  _instance = this;
   _classlist_file = file;
   _file = fopen(file, "r");
+  _line_no = 0;
+  _interfaces = new (ResourceObj::C_HEAP, mtClass) GrowableArray<int>(10, true);
+
   if (_file == NULL) {
     char errmsg[JVM_MAXPATHLEN];
     os::lasterror(errmsg, JVM_MAXPATHLEN);
@@ -41,6 +60,7 @@
   if (_file) {
     fclose(_file);
   }
+  _instance = NULL;
 }
 
 bool ClassListParser::parse_one_line() {
@@ -48,10 +68,10 @@
     if (fgets(_line, sizeof(_line), _file) == NULL) {
       return false;
     }
-    int line_len = (int)strlen(_line);
-    if (line_len > _max_allowed_line_len) {
-      tty->print_cr("input line too long (must be no longer than %d chars)", _max_allowed_line_len);
-      vm_exit_during_initialization("Loading classlist failed");
+    ++ _line_no;
+    _line_len = (int)strlen(_line);
+    if (_line_len > _max_allowed_line_len) {
+      error("input line too long (must be no longer than %d chars)", _max_allowed_line_len);
     }
     if (*_line == '#') { // comment
       continue;
@@ -59,8 +79,380 @@
     break;
   }
 
-  // Remove trailing \r\n
-  _line[strcspn(_line, "\r\n")] = 0;
+  _id = _unspecified;
+  _super = _unspecified;
+  _interfaces->clear();
+  _source = NULL;
+  _interfaces_specified = false;
+
+  {
+    int len = (int)strlen(_line);
+    int i;
+    // Replace \t\r\n with ' '
+    for (i=0; i<len; i++) {
+      if (_line[i] == '\t' || _line[i] == '\r' || _line[i] == '\n') {
+        _line[i] = ' ';
+      }
+    }
+
+    // Remove trailing newline/space
+    while (len > 0) {
+      if (_line[len-1] == ' ') {
+        _line[len-1] = '\0';
+        len --;
+      } else {
+        break;
+      }
+    }
+    _line_len = len;
+    _class_name = _line;
+  }
+
+  if ((_token = strchr(_line, ' ')) == NULL) {
+    // No optional arguments are specified.
+    return true;
+  }
+
+  // Mark the end of the name, and go to the next input char
+  *_token++ = '\0';
+
+  while (*_token) {
+    skip_whitespaces();
+
+    if (parse_int_option("id:", &_id)) {
+      continue;
+    } else if (parse_int_option("super:", &_super)) {
+      check_already_loaded("Super class", _super);
+      continue;
+    } else if (skip_token("interfaces:")) {
+      int i;
+      while (try_parse_int(&i)) {
+        check_already_loaded("Interface", i);
+        _interfaces->append(i);
+      }
+    } else if (skip_token("source:")) {
+      skip_whitespaces();
+      _source = _token;
+      char* s = strchr(_token, ' ');
+      if (s == NULL) {
+        break; // end of input line
+      } else {
+        *s = '\0'; // mark the end of _source
+        _token = s+1;
+      }
+    } else {
+      error("Unknown input");
+    }
+  }
+
+  // if src is specified
+  //     id super interfaces must all be specified
+  //     loader may be specified
+  // else
+  //     # the class is loaded from classpath
+  //     id may be specified
+  //     super, interfaces, loader must not be specified
   return true;
 }
 
+void ClassListParser::skip_whitespaces() {
+  while (*_token == ' ' || *_token == '\t') {
+    _token ++;
+  }
+}
+
+void ClassListParser::skip_non_whitespaces() {
+  while (*_token && *_token != ' ' && *_token != '\t') {
+    _token ++;
+  }
+}
+
+void ClassListParser::parse_int(int* value) {
+  skip_whitespaces();
+  if (sscanf(_token, "%i", value) == 1) {
+    skip_non_whitespaces();
+    if (*value < 0) {
+      error("Error: negative integers not allowed (%d)", *value);
+    }
+  } else {
+    error("Error: expected integer");
+  }
+}
+
+bool ClassListParser::try_parse_int(int* value) {
+  skip_whitespaces();
+  if (sscanf(_token, "%i", value) == 1) {
+    skip_non_whitespaces();
+    return true;
+  }
+  return false;
+}
+
+bool ClassListParser::skip_token(const char* option_name) {
+  size_t len = strlen(option_name);
+  if (strncmp(_token, option_name, len) == 0) {
+    _token += len;
+    return true;
+  } else {
+    return false;
+  }
+}
+
+bool ClassListParser::parse_int_option(const char* option_name, int* value) {
+  if (skip_token(option_name)) {
+    if (*value != _unspecified) {
+      error("%s specified twice", option_name);
+    } else {
+      parse_int(value);
+      return true;
+    }
+  }
+  return false;
+}
+
+void ClassListParser::print_specified_interfaces() {
+  const int n = _interfaces->length();
+  jio_fprintf(defaultStream::error_stream(), "Currently specified interfaces[%d] = {\n", n);
+  for (int i=0; i<n; i++) {
+    InstanceKlass* k = lookup_class_by_id(_interfaces->at(i));
+    jio_fprintf(defaultStream::error_stream(), "  %4d = %s\n", _interfaces->at(i), k->name()->as_klass_external_name());
+  }
+  jio_fprintf(defaultStream::error_stream(), "}\n");
+}
+
+void ClassListParser::print_actual_interfaces(InstanceKlass *ik) {
+  int n = ik->local_interfaces()->length();
+  jio_fprintf(defaultStream::error_stream(), "Actual interfaces[%d] = {\n", n);
+  for (int i = 0; i < n; i++) {
+    InstanceKlass* e = InstanceKlass::cast(ik->local_interfaces()->at(i));
+    jio_fprintf(defaultStream::error_stream(), "  %s\n", e->name()->as_klass_external_name());
+  }
+  jio_fprintf(defaultStream::error_stream(), "}\n");
+}
+
+void ClassListParser::error(const char *msg, ...) {
+  va_list ap;
+  va_start(ap, msg);
+  int error_index = _token - _line;
+  if (error_index >= _line_len) {
+    error_index = _line_len - 1;
+  }
+  if (error_index < 0) {
+    error_index = 0;
+  }
+
+  jio_fprintf(defaultStream::error_stream(),
+              "An error has occurred while processing class list file %s %d:%d.\n",
+              _classlist_file, _line_no, (error_index + 1));
+  jio_vfprintf(defaultStream::error_stream(), msg, ap);
+
+  if (_line_len <= 0) {
+    jio_fprintf(defaultStream::error_stream(), "\n");
+  } else {
+    jio_fprintf(defaultStream::error_stream(), ":\n");
+    for (int i=0; i<_line_len; i++) {
+      char c = _line[i];
+      if (c == '\0') {
+        jio_fprintf(defaultStream::error_stream(), "%s", " ");
+      } else {
+        jio_fprintf(defaultStream::error_stream(), "%c", c);
+      }
+    }
+    jio_fprintf(defaultStream::error_stream(), "\n");
+    for (int i=0; i<error_index; i++) {
+      jio_fprintf(defaultStream::error_stream(), "%s", " ");
+    }
+    jio_fprintf(defaultStream::error_stream(), "^\n");
+  }
+
+  vm_exit_during_initialization("class list format error.", NULL);
+  va_end(ap);
+}
+
+// This function is used for loading classes for customized class loaders
+// during archive dumping.
+InstanceKlass* ClassListParser::load_class_from_source(Symbol* class_name, TRAPS) {
+#if !(defined(_LP64) && (defined(LINUX)|| defined(SOLARIS) || defined(AIX)))
+  // The only supported platforms are: (1) Linux/64-bit; (2) Solaris/64-bit; (3) AIX/64-bit
+  //
+  // This #if condition should be in sync with the areCustomLoadersSupportedForCDS
+  // method in test/lib/jdk/test/lib/Platform.java.
+  error("AppCDS custom class loaders not supported on this platform");
+#endif
+
+  assert(UseAppCDS, "must be");
+  if (!is_super_specified()) {
+    error("If source location is specified, super class must be also specified");
+  }
+  if (!is_id_specified()) {
+    error("If source location is specified, id must be also specified");
+  }
+  InstanceKlass* k = ClassLoaderExt::load_class(class_name, _source, THREAD);
+
+  if (strncmp(_class_name, "java/", 5) == 0) {
+    log_info(cds)("Prohibited package for non-bootstrap classes: %s.class from %s",
+          _class_name, _source);
+    return NULL;
+  }
+
+  if (k != NULL) {
+    if (k->local_interfaces()->length() != _interfaces->length()) {
+      print_specified_interfaces();
+      print_actual_interfaces(k);
+      error("The number of interfaces (%d) specified in class list does not match the class file (%d)",
+            _interfaces->length(), k->local_interfaces()->length());
+    }
+
+    if (!SystemDictionaryShared::add_non_builtin_klass(class_name, ClassLoaderData::the_null_class_loader_data(),
+                                                       k, THREAD)) {
+      error("Duplicated class %s", _class_name);
+    }
+
+    // This tells JVM_FindLoadedClass to not find this class.
+    k->set_shared_classpath_index(UNREGISTERED_INDEX);
+  }
+
+  return k;
+}
+
+InstanceKlass* ClassListParser::load_current_class(TRAPS) {
+  TempNewSymbol class_name_symbol = SymbolTable::new_symbol(_class_name, THREAD);
+  guarantee(!HAS_PENDING_EXCEPTION, "Exception creating a symbol.");
+
+  InstanceKlass *klass = NULL;
+  if (!is_loading_from_source()) {
+    if (is_super_specified()) {
+      error("If source location is not specified, super class must not be specified");
+    }
+    if (are_interfaces_specified()) {
+      error("If source location is not specified, interface(s) must not be specified");
+    }
+
+    bool non_array = !FieldType::is_array(class_name_symbol);
+
+    Handle s = java_lang_String::create_from_symbol(class_name_symbol, CHECK_0);
+    // Translate to external class name format, i.e., convert '/' chars to '.'
+    Handle string = java_lang_String::externalize_classname(s, CHECK_0);
+    JavaValue result(T_OBJECT);
+    InstanceKlass* spec_klass =  non_array ?
+      SystemDictionary::ClassLoader_klass() : SystemDictionary::Class_klass();
+    Symbol* method_name = non_array ?
+      vmSymbols::loadClass_name() : vmSymbols::forName_name();
+    Handle loader = Handle(THREAD, SystemDictionary::java_system_loader());
+
+    if (non_array) {
+      JavaCalls::call_virtual(&result,
+                              loader, //SystemDictionary::java_system_loader(),
+                              spec_klass,
+                              method_name, //vmSymbols::loadClass_name(),
+                              vmSymbols::string_class_signature(),
+                              string,
+                              THREAD);
+    } else {
+      JavaCalls::call_static(&result,
+                             spec_klass,
+                             method_name,
+                             vmSymbols::string_class_signature(),
+                             string,
+                             CHECK_NULL);
+    }
+    assert(result.get_type() == T_OBJECT, "just checking");
+    oop obj = (oop) result.get_jobject();
+    if (!HAS_PENDING_EXCEPTION && (obj != NULL)) {
+      if (non_array) {
+        klass = InstanceKlass::cast(java_lang_Class::as_Klass(obj));
+      } else {
+        klass = static_cast<InstanceKlass*>(java_lang_Class::array_klass_acquire(obj));
+      }
+    } else { // load classes in bootclasspath/a
+      if (HAS_PENDING_EXCEPTION) {
+        CLEAR_PENDING_EXCEPTION;
+      }
+
+      if (non_array) {
+        Klass* k = SystemDictionary::resolve_or_null(class_name_symbol, CHECK_NULL);
+        if (k != NULL) {
+          klass = InstanceKlass::cast(k);
+        } else {
+          if (!HAS_PENDING_EXCEPTION) {
+            THROW_NULL(vmSymbols::java_lang_ClassNotFoundException());
+          }
+        }
+      }
+    }
+  } else {
+    // If "source:" tag is specified, all super class and super interfaces must be specified in the
+    // class list file.
+    if (UseAppCDS) {
+      klass = load_class_from_source(class_name_symbol, CHECK_NULL);
+    }
+  }
+
+  if (klass != NULL && is_id_specified()) {
+    int id = this->id();
+    SystemDictionaryShared::update_shared_entry(klass, id);
+    InstanceKlass* old = table()->lookup(id);
+    if (old != NULL && old != klass) {
+      error("Duplicated ID %d for class %s", id, _class_name);
+    }
+    table()->add(id, klass);
+  }
+
+  return klass;
+}
+
+bool ClassListParser::is_loading_from_source() {
+  return (_source != NULL);
+}
+
+InstanceKlass* ClassListParser::lookup_class_by_id(int id) {
+  InstanceKlass* klass = table()->lookup(id);
+  if (klass == NULL) {
+    error("Class ID %d has not been defined", id);
+  }
+  return klass;
+}
+
+
+InstanceKlass* ClassListParser::lookup_super_for_current_class(Symbol* super_name) {
+  if (!is_loading_from_source()) {
+    return NULL;
+  }
+
+  InstanceKlass* k = lookup_class_by_id(super());
+  if (super_name != k->name()) {
+    error("The specified super class %s (id %d) does not match actual super class %s",
+          k->name()->as_klass_external_name(), super(),
+          super_name->as_klass_external_name());
+  }
+  return k;
+}
+
+InstanceKlass* ClassListParser::lookup_interface_for_current_class(Symbol* interface_name) {
+  if (!is_loading_from_source()) {
+    return NULL;
+  }
+
+  const int n = _interfaces->length();
+  if (n == 0) {
+    error("Class %s implements the interface %s, but no interface has been specified in the input line",
+          _class_name, interface_name->as_klass_external_name());
+    ShouldNotReachHere();
+  }
+
+  int i;
+  for (i=0; i<n; i++) {
+    InstanceKlass* k = lookup_class_by_id(_interfaces->at(i));
+    if (interface_name == k->name()) {
+      return k;
+    }
+  }
+
+  // interface_name is not specified by the "interfaces:" keyword.
+  print_specified_interfaces();
+  error("The interface %s implemented by class %s does not match any of the specified interface IDs",
+        interface_name->as_klass_external_name(), _class_name);
+  ShouldNotReachHere();
+  return NULL;
+}
+
--- a/src/hotspot/share/classfile/classListParser.hpp	Wed Dec 06 15:14:13 2017 -0800
+++ b/src/hotspot/share/classfile/classListParser.hpp	Sat Dec 02 06:51:10 2017 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, 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
@@ -27,30 +27,122 @@
 
 #include "utilities/exceptions.hpp"
 #include "utilities/globalDefinitions.hpp"
+#include "utilities/hashtable.hpp"
+
+class CDSClassInfo;
+
+// Look up from ID -> InstanceKlass*
+class ID2KlassTable : public Hashtable<InstanceKlass*, mtClass> {
+public:
+  ID2KlassTable() : Hashtable<InstanceKlass*, mtClass>(1987, sizeof(HashtableEntry<InstanceKlass*, mtClass>)) { }
+  void add(int id, InstanceKlass* klass) {
+    unsigned int hash = (unsigned int)id;
+    HashtableEntry<InstanceKlass*, mtClass>* entry = new_entry(hash, klass);
+    add_entry(hash_to_index(hash), entry);
+  }
+
+  InstanceKlass* lookup(int id) {
+    unsigned int hash = (unsigned int)id;
+    int index = hash_to_index(id);
+    for (HashtableEntry<InstanceKlass*, mtClass>* e = bucket(index); e != NULL; e = e->next()) {
+      if (e->hash() == hash) {
+        return e->literal();
+      }
+    }
+    return NULL;
+  }
+};
 
 class ClassListParser : public StackObj {
   enum {
+    _unspecified      = -999,
+
     // Max number of bytes allowed per line in the classlist.
-    // Theoretically Java class names could be 65535 bytes in length. In reality,
+    // Theoretically Java class names could be 65535 bytes in length. Also, an input line
+    // could have a very long path name up to JVM_MAXPATHLEN bytes in length. In reality,
     // 4K bytes is more than enough.
     _max_allowed_line_len = 4096,
     _line_buf_extra       = 10, // for detecting input too long
     _line_buf_size        = _max_allowed_line_len + _line_buf_extra
   };
 
+  static ClassListParser* _instance; // the singleton.
   const char* _classlist_file;
   FILE* _file;
-  char  _line[_line_buf_size];  // The buffer that holds the current line.
 
+  ID2KlassTable _id2klass_table;
+
+  // The following field contains information from the *current* line being
+  // parsed.
+  char                _line[_line_buf_size];  // The buffer that holds the current line. Some characters in
+                                              // the buffer may be overwritten by '\0' during parsing.
+  int                 _line_len;              // Original length of the input line.
+  int                 _line_no;               // Line number for current line being parsed
+  const char*         _class_name;
+  int                 _id;
+  int                 _super;
+  GrowableArray<int>* _interfaces;
+  bool                _interfaces_specified;
+  const char*         _source;
+
+  bool parse_int_option(const char* option_name, int* value);
+  InstanceKlass* load_class_from_source(Symbol* class_name, TRAPS);
+  ID2KlassTable *table() {
+    return &_id2klass_table;
+  }
+  InstanceKlass* lookup_class_by_id(int id);
+  void print_specified_interfaces();
+  void print_actual_interfaces(InstanceKlass *ik);
 public:
   ClassListParser(const char* file);
   ~ClassListParser();
+
+  static ClassListParser* instance() {
+    return _instance;
+  }
   bool parse_one_line();
+  char* _token;
+  void error(const char* msg, ...);
+  void parse_int(int* value);
+  bool try_parse_int(int* value);
+  bool skip_token(const char* option_name);
+  void skip_whitespaces();
+  void skip_non_whitespaces();
+
+  bool is_id_specified() {
+    return _id != _unspecified;
+  }
+  bool is_super_specified() {
+    return _super != _unspecified;
+  }
+  bool are_interfaces_specified() {
+    return _interfaces->length() > 0;
+  }
+  int id() {
+    assert(is_id_specified(), "do not query unspecified id");
+    return _id;
+  }
+  int super() {
+    assert(is_super_specified(), "do not query unspecified super");
+    return _super;
+  }
+  void check_already_loaded(const char* which, int id) {
+    if (_id2klass_table.lookup(id) == NULL) {
+      error("%s id %d is not yet loaded", which, id);
+    }
+  }
 
   const char* current_class_name() {
-    return _line;
+    return _class_name;
   }
+
+  InstanceKlass* load_current_class(TRAPS);
+
+  bool is_loading_from_source();
+
+  // Look up the super or interface of the current class being loaded
+  // (in this->load_current_class()).
+  InstanceKlass* lookup_super_for_current_class(Symbol* super_name);
+  InstanceKlass* lookup_interface_for_current_class(Symbol* interface_name);
 };
-
-
-#endif // SHARE_VM_MEMORY_CLASSLISTPARSER_HPP
+#endif
--- a/src/hotspot/share/classfile/classLoader.hpp	Wed Dec 06 15:14:13 2017 -0800
+++ b/src/hotspot/share/classfile/classLoader.hpp	Sat Dec 02 06:51:10 2017 +0100
@@ -26,6 +26,7 @@
 #define SHARE_VM_CLASSFILE_CLASSLOADER_HPP
 
 #include "jimage.hpp"
+#include "runtime/handles.hpp"
 #include "runtime/orderAccess.hpp"
 #include "runtime/perfData.hpp"
 #include "utilities/exceptions.hpp"
@@ -42,6 +43,7 @@
 class JImageFile;
 class ClassFileStream;
 class PackageEntry;
+template <typename T> class GrowableArray;
 
 class ClassPathEntry : public CHeapObj<mtClass> {
 private:
--- a/src/hotspot/share/classfile/classLoaderExt.cpp	Wed Dec 06 15:14:13 2017 -0800
+++ b/src/hotspot/share/classfile/classLoaderExt.cpp	Sat Dec 02 06:51:10 2017 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, 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
@@ -23,14 +23,329 @@
  */
 
 #include "precompiled.hpp"
+#include "classfile/classFileParser.hpp"
+#include "classfile/classFileStream.hpp"
 #include "classfile/classListParser.hpp"
+#include "classfile/classLoader.hpp"
 #include "classfile/classLoaderExt.hpp"
-#include "classfile/symbolTable.hpp"
-#include "classfile/systemDictionary.hpp"
+#include "classfile/classLoaderData.inline.hpp"
+#include "classfile/klassFactory.hpp"
+#include "classfile/sharedClassUtil.hpp"
+#include "classfile/sharedPathsMiscInfo.hpp"
+#include "classfile/systemDictionaryShared.hpp"
+#include "classfile/vmSymbols.hpp"
+#include "memory/allocation.inline.hpp"
+#include "memory/filemap.hpp"
+#include "memory/resourceArea.hpp"
+#include "oops/instanceKlass.hpp"
+#include "oops/oop.inline.hpp"
+#include "oops/symbol.hpp"
+#include "runtime/arguments.hpp"
+#include "runtime/java.hpp"
+#include "runtime/javaCalls.hpp"
+#include "runtime/os.hpp"
+#include "services/threadService.hpp"
+#include "utilities/stringUtils.hpp"
 
+jshort ClassLoaderExt::_app_paths_start_index = ClassLoaderExt::max_classpath_index;
+bool ClassLoaderExt::_has_app_classes = false;
+bool ClassLoaderExt::_has_platform_classes = false;
+
+void ClassLoaderExt::setup_app_search_path() {
+  assert(DumpSharedSpaces, "this function is only used with -Xshare:dump and -XX:+UseAppCDS");
+  _app_paths_start_index = ClassLoader::num_boot_classpath_entries();
+  char* app_class_path = os::strdup(Arguments::get_appclasspath());
+
+  if (strcmp(app_class_path, ".") == 0) {
+    // This doesn't make any sense, even for AppCDS, so let's skip it. We
+    // don't want to throw an error here because -cp "." is usually assigned
+    // by the launcher when classpath is not specified.
+    trace_class_path("app loader class path (skipped)=", app_class_path);
+  } else {
+    trace_class_path("app loader class path=", app_class_path);
+    shared_paths_misc_info()->add_app_classpath(app_class_path);
+    ClassLoader::setup_app_search_path(app_class_path);
+  }
+}
+
+char* ClassLoaderExt::read_manifest(ClassPathEntry* entry, jint *manifest_size, bool clean_text, TRAPS) {
+  const char* name = "META-INF/MANIFEST.MF";
+  char* manifest;
+  jint size;
+
+  assert(entry->is_jar_file(), "must be");
+  manifest = (char*) ((ClassPathZipEntry*)entry )->open_entry(name, &size, true, CHECK_NULL);
+
+  if (manifest == NULL) { // No Manifest
+    *manifest_size = 0;
+    return NULL;
+  }
+
+
+  if (clean_text) {
+    // See http://docs.oracle.com/javase/6/docs/technotes/guides/jar/jar.html#JAR%20Manifest
+    // (1): replace all CR/LF and CR with LF
+    StringUtils::replace_no_expand(manifest, "\r\n", "\n");
+
+    // (2) remove all new-line continuation (remove all "\n " substrings)
+    StringUtils::replace_no_expand(manifest, "\n ", "");
+  }
+
+  *manifest_size = (jint)strlen(manifest);
+  return manifest;
+}
+
+char* ClassLoaderExt::get_class_path_attr(const char* jar_path, char* manifest, jint manifest_size) {
+  const char* tag = "Class-Path: ";
+  const int tag_len = (int)strlen(tag);
+  char* found = NULL;
+  char* line_start = manifest;
+  char* end = manifest + manifest_size;
+
+  assert(*end == 0, "must be nul-terminated");
+
+  while (line_start < end) {
+    char* line_end = strchr(line_start, '\n');
+    if (line_end == NULL) {
+      // JAR spec require the manifest file to be terminated by a new line.
+      break;
+    }
+    if (strncmp(tag, line_start, tag_len) == 0) {
+      if (found != NULL) {
+        // Same behavior as jdk/src/share/classes/java/util/jar/Attributes.java
+        // If duplicated entries are found, the last one is used.
+        tty->print_cr("Warning: Duplicate name in Manifest: %s.\n"
+                      "Ensure that the manifest does not have duplicate entries, and\n"
+                      "that blank lines separate individual sections in both your\n"
+                      "manifest and in the META-INF/MANIFEST.MF entry in the jar file:\n%s\n", tag, jar_path);
+      }
+      found = line_start + tag_len;
+      assert(found <= line_end, "sanity");
+      *line_end = '\0';
+    }
+    line_start = line_end + 1;
+  }
+  return found;
+}
+
+void ClassLoaderExt::process_jar_manifest(ClassPathEntry* entry,
+                                          bool check_for_duplicates) {
+  Thread* THREAD = Thread::current();
+  ResourceMark rm(THREAD);
+  jint manifest_size;
+  char* manifest = read_manifest(entry, &manifest_size, CHECK);
+
+  if (manifest == NULL) {
+    return;
+  }
+
+  if (strstr(manifest, "Extension-List:") != NULL) {
+    tty->print_cr("-Xshare:dump does not support Extension-List in JAR manifest: %s", entry->name());
+    vm_exit(1);
+  }
+
+  char* cp_attr = get_class_path_attr(entry->name(), manifest, manifest_size);
+
+  if (cp_attr != NULL && strlen(cp_attr) > 0) {
+    trace_class_path("found Class-Path: ", cp_attr);
+
+    char sep = os::file_separator()[0];
+    const char* dir_name = entry->name();
+    const char* dir_tail = strrchr(dir_name, sep);
+    int dir_len;
+    if (dir_tail == NULL) {
+      dir_len = 0;
+    } else {
+      dir_len = dir_tail - dir_name + 1;
+    }
+
+    // Split the cp_attr by spaces, and add each file
+    char* file_start = cp_attr;
+    char* end = file_start + strlen(file_start);
+
+    while (file_start < end) {
+      char* file_end = strchr(file_start, ' ');
+      if (file_end != NULL) {
+        *file_end = 0;
+        file_end += 1;
+      } else {
+        file_end = end;
+      }
+
+      int name_len = (int)strlen(file_start);
+      if (name_len > 0) {
+        ResourceMark rm(THREAD);
+        char* libname = NEW_RESOURCE_ARRAY(char, dir_len + name_len + 1);
+        *libname = 0;
+        strncat(libname, dir_name, dir_len);
+        strncat(libname, file_start, name_len);
+        trace_class_path("library = ", libname);
+        ClassLoader::update_class_path_entry_list(libname, true, false);
+      }
+
+      file_start = file_end;
+    }
+  }
+}
+
+void ClassLoaderExt::setup_search_paths() {
+  if (UseAppCDS) {
+    shared_paths_misc_info()->record_app_offset();
+    ClassLoaderExt::setup_app_search_path();
+  }
+}
+
+Thread* ClassLoaderExt::Context::_dump_thread = NULL;
+
+bool ClassLoaderExt::check(ClassLoaderExt::Context *context,
+                           const ClassFileStream* stream,
+                           const int classpath_index) {
+  if (stream != NULL) {
+    // Ignore any App classes from signed JAR file during CDS archiving
+    // dumping
+    if (DumpSharedSpaces &&
+        SharedClassUtil::is_classpath_entry_signed(classpath_index) &&
+        classpath_index >= _app_paths_start_index) {
+      tty->print_cr("Preload Warning: Skipping %s from signed JAR",
+                    context->class_name());
+      return false;
+    }
+    if (classpath_index >= _app_paths_start_index) {
+      _has_app_classes = true;
+      _has_platform_classes = true;
+    }
+  }
+
+  return true;
+}
+
+void ClassLoaderExt::record_result(ClassLoaderExt::Context *context,
+                                   Symbol* class_name,
+                                   const s2 classpath_index,
+                                   InstanceKlass* result,
+                                   TRAPS) {
+  assert(DumpSharedSpaces, "Sanity");
+
+  // We need to remember where the class comes from during dumping.
+  oop loader = result->class_loader();
+  s2 classloader_type = ClassLoader::BOOT_LOADER;
+  if (SystemDictionary::is_system_class_loader(loader)) {
+    classloader_type = ClassLoader::APP_LOADER;
+    ClassLoaderExt::set_has_app_classes();
+  } else if (SystemDictionary::is_platform_class_loader(loader)) {
+    classloader_type = ClassLoader::PLATFORM_LOADER;
+    ClassLoaderExt::set_has_platform_classes();
+  }
+  result->set_shared_classpath_index(classpath_index);
+  result->set_class_loader_type(classloader_type);
+}
+
+void ClassLoaderExt::finalize_shared_paths_misc_info() {
+  if (UseAppCDS) {
+    if (!_has_app_classes) {
+      shared_paths_misc_info()->pop_app();
+    }
+  }
+}
+
+// Load the class of the given name from the location given by path. The path is specified by
+// the "source:" in the class list file (see classListParser.cpp), and can be a directory or
+// a JAR file.
+InstanceKlass* ClassLoaderExt::load_class(Symbol* name, const char* path, TRAPS) {
+
+  assert(name != NULL, "invariant");
+  assert(DumpSharedSpaces && UseAppCDS, "this function is only used with -Xshare:dump and -XX:+UseAppCDS");
+  ResourceMark rm(THREAD);
+  const char* class_name = name->as_C_string();
+
+  const char* file_name = file_name_for_class_name(class_name,
+                                                   name->utf8_length());
+  assert(file_name != NULL, "invariant");
+
+  // Lookup stream for parsing .class file
+  ClassFileStream* stream = NULL;
+  ClassPathEntry* e = find_classpath_entry_from_cache(path, CHECK_NULL);
+  if (e == NULL) {
+    return NULL;
+  }
+  {
+    PerfClassTraceTime vmtimer(perf_sys_class_lookup_time(),
+                               ((JavaThread*) THREAD)->get_thread_stat()->perf_timers_addr(),
+                               PerfClassTraceTime::CLASS_LOAD);
+    stream = e->open_stream(file_name, CHECK_NULL);
+  }
+
+  if (NULL == stream) {
+    tty->print_cr("Preload Warning: Cannot find %s", class_name);
+    return NULL;
+  }
+
+  assert(stream != NULL, "invariant");
+  stream->set_verify(true);
+
+  ClassLoaderData* loader_data = ClassLoaderData::the_null_class_loader_data();
+  Handle protection_domain;
+
+  InstanceKlass* result = KlassFactory::create_from_stream(stream,
+                                                           name,
+                                                           loader_data,
+                                                           protection_domain,
+                                                           NULL, // host_klass
+                                                           NULL, // cp_patches
+                                                           THREAD);
+
+  if (HAS_PENDING_EXCEPTION) {
+    tty->print_cr("Preload Error: Failed to load %s", class_name);
+    return NULL;
+  }
+  result->set_shared_classpath_index(UNREGISTERED_INDEX);
+  SystemDictionaryShared::set_shared_class_misc_info(result, stream);
+  return result;
+}
+
+struct CachedClassPathEntry {
+  const char* _path;
+  ClassPathEntry* _entry;
+};
+
+static GrowableArray<CachedClassPathEntry>* cached_path_entries = NULL;
+
+ClassPathEntry* ClassLoaderExt::find_classpath_entry_from_cache(const char* path, TRAPS) {
+  // This is called from dump time so it's single threaded and there's no need for a lock.
+  assert(DumpSharedSpaces && UseAppCDS, "this function is only used with -Xshare:dump and -XX:+UseAppCDS");
+  if (cached_path_entries == NULL) {
+    cached_path_entries = new (ResourceObj::C_HEAP, mtClass) GrowableArray<CachedClassPathEntry>(20, /*c heap*/ true);
+  }
+  CachedClassPathEntry ccpe;
+  for (int i=0; i<cached_path_entries->length(); i++) {
+    ccpe = cached_path_entries->at(i);
+    if (strcmp(ccpe._path, path) == 0) {
+      if (i != 0) {
+        // Put recent entries at the beginning to speed up searches.
+        cached_path_entries->remove_at(i);
+        cached_path_entries->insert_before(0, ccpe);
+      }
+      return ccpe._entry;
+    }
+  }
+
+  struct stat st;
+  if (os::stat(path, &st) != 0) {
+    // File or directory not found
+    return NULL;
+  }
+  ClassPathEntry* new_entry = NULL;
+
+  new_entry = create_class_path_entry(path, &st, false, false, CHECK_NULL);
+  if (new_entry == NULL) {
+    return NULL;
+  }
+  ccpe._path = strdup(path);
+  ccpe._entry = new_entry;
+  cached_path_entries->insert_before(0, ccpe);
+  return new_entry;
+}
 
 Klass* ClassLoaderExt::load_one_class(ClassListParser* parser, TRAPS) {
-  TempNewSymbol class_name_symbol = SymbolTable::new_symbol(parser->current_class_name(), THREAD);
-  guarantee(!HAS_PENDING_EXCEPTION, "Exception creating a symbol.");
-  return SystemDictionary::resolve_or_null(class_name_symbol, THREAD);
+  return parser->load_current_class(THREAD);
 }
--- a/src/hotspot/share/classfile/classLoaderExt.hpp	Wed Dec 06 15:14:13 2017 -0800
+++ b/src/hotspot/share/classfile/classLoaderExt.hpp	Sat Dec 02 06:51:10 2017 +0100
@@ -26,65 +26,152 @@
 #define SHARE_VM_CLASSFILE_CLASSLOADEREXT_HPP
 
 #include "classfile/classLoader.hpp"
-#include "classfile/systemDictionary.hpp"
-#include "oops/instanceKlass.hpp"
-#include "runtime/handles.hpp"
+#include "utilities/macros.hpp"
 
-class ClassListParser;
+CDS_ONLY(class SharedPathsMiscInfoExt;)
+CDS_ONLY(class ClassListParser;)
 
 class ClassLoaderExt: public ClassLoader { // AllStatic
 public:
-
+  enum SomeConstants {
+    max_classpath_index = 0x7fff
+  };
+  // ClassLoaderExt::Context --
+  //
+  // This is used by DumpSharedSpaces only - it enforces the same classloader
+  // delegation model as would be in run-time. I.e.,
+  // + classes defined by the NULL class loader cannot load classes in the PLATFORM or APP paths.
+  // + classes defined by the PLATFORM class loader cannot load classes in the APP paths.
   class Context {
+    static Thread* _dump_thread;
+    const char* _class_name;
     const char* _file_name;
   public:
+    const char* class_name() {
+      return _class_name;
+    }
+    const char* file_name() {
+      return _file_name;
+    }
+
     Context(const char* class_name, const char* file_name, TRAPS) {
+      _class_name = class_name;
       _file_name = file_name;
+#if INCLUDE_CDS
+      if (!DumpSharedSpaces && !UseSharedSpaces) {
+        // Must not modify _app_paths_start_index if we're not using CDS.
+        assert(_app_paths_start_index == ClassLoaderExt::max_classpath_index, "must be");
+      }
+#endif
     }
 
     bool check(const ClassFileStream* stream, const int classpath_index) {
-      return true;
+      CDS_ONLY(return ClassLoaderExt::check(this, stream, classpath_index);)
+      NOT_CDS(return true;)
     }
 
     bool should_verify(int classpath_index) {
-      return false;
+      CDS_ONLY(return (classpath_index >= _app_paths_start_index);)
+      NOT_CDS(return false;)
     }
 
     void record_result(Symbol* class_name,
                        const s2 classpath_index,
-                       InstanceKlass* result, TRAPS) {
+                       InstanceKlass* result,
+                       TRAPS) {
 #if INCLUDE_CDS
-      assert(DumpSharedSpaces, "Sanity");
-      oop loader = result->class_loader();
-      s2 classloader_type = ClassLoader::BOOT_LOADER;
-      if (SystemDictionary::is_system_class_loader(loader)) {
-        classloader_type = ClassLoader::APP_LOADER;
-        ClassLoaderExt::set_has_app_classes();
-      } else if (SystemDictionary::is_platform_class_loader(loader)) {
-        classloader_type = ClassLoader::PLATFORM_LOADER;
-        ClassLoaderExt::set_has_platform_classes();
-      }
-      result->set_shared_classpath_index(classpath_index);
-      result->set_class_loader_type(classloader_type);
+      ClassLoaderExt::record_result(this, class_name, classpath_index, result, THREAD);
 #endif
     }
-  };
 
+    ~Context() {
+#if INCLUDE_CDS
+      if (!DumpSharedSpaces && !UseSharedSpaces) {
+        // Must not modify app_paths_start_index if we're not using CDS.
+        assert(_app_paths_start_index == ClassLoaderExt::max_classpath_index, "must be");
+      }
+#endif
+    }
+  }; // end ClassLoaderExt::Context
+
+private:
+#if INCLUDE_CDS
+  static char* get_class_path_attr(const char* jar_path, char* manifest, jint manifest_size);
+  static void setup_app_search_path(); // Only when -Xshare:dump
+  static SharedPathsMiscInfoExt* shared_paths_misc_info() {
+    return (SharedPathsMiscInfoExt*)_shared_paths_misc_info;
+  }
+  static jshort _app_paths_start_index; // index of first app JAR in shared classpath entry table
+  static bool _has_app_classes;
+  static bool _has_platform_classes;
+#endif
+
+public:
+  CDS_ONLY(static void process_jar_manifest(ClassPathEntry* entry, bool check_for_duplicates);)
+
+  // Called by JVMTI code to add boot classpath
   static void append_boot_classpath(ClassPathEntry* new_entry) {
+#if INCLUDE_CDS
+    if (UseAppCDS) {
+      warning("UseAppCDS is disabled because bootstrap classpath has been appended");
+      UseAppCDS = false;
+    }
+#endif
     ClassLoader::add_to_boot_append_entries(new_entry);
   }
-  static void setup_search_paths() {}
+
+  static void setup_search_paths() NOT_CDS_RETURN;
+
+#if INCLUDE_CDS
+private:
+  static char* read_manifest(ClassPathEntry* entry, jint *manifest_size, bool clean_text, TRAPS);
+  static ClassPathEntry* find_classpath_entry_from_cache(const char* path, TRAPS);
+
+public:
+  static char* read_manifest(ClassPathEntry* entry, jint *manifest_size, TRAPS) {
+    // Remove all the new-line continuations (which wrap long lines at 72 characters, see
+    // http://docs.oracle.com/javase/6/docs/technotes/guides/jar/jar.html#JAR%20Manifest), so
+    // that the manifest is easier to parse.
+    return read_manifest(entry, manifest_size, true, THREAD);
+  }
+  static char* read_raw_manifest(ClassPathEntry* entry, jint *manifest_size, TRAPS) {
+    // Do not remove new-line continuations, so we can easily pass it as an argument to
+    // java.util.jar.Manifest.getManifest() at run-time.
+    return read_manifest(entry, manifest_size, false, THREAD);
+  }
+
+  static void finalize_shared_paths_misc_info();
+
+  static jshort app_paths_start_index() { return _app_paths_start_index; }
+
+  static void init_paths_start_index(jshort app_start) {
+    _app_paths_start_index = app_start;
+  }
+
   static bool is_boot_classpath(int classpath_index) {
-   return true;
- }
+    return classpath_index < _app_paths_start_index;
+  }
+
+  static bool has_platform_or_app_classes() {
+    return _has_app_classes || _has_platform_classes;
+  }
+
+  static bool check(class ClassLoaderExt::Context *context,
+                    const ClassFileStream* stream,
+                    const int classpath_index);
+
+  static void record_result(class ClassLoaderExt::Context *context,
+                            Symbol* class_name,
+                            const s2 classpath_index,
+                            InstanceKlass* result, TRAPS);
+  static InstanceKlass* load_class(Symbol* h_name, const char* path, TRAPS);
   static Klass* load_one_class(ClassListParser* parser, TRAPS);
-#if INCLUDE_CDS
-  static void set_has_app_classes() {}
-  static void set_has_platform_classes() {}
-  static char* read_manifest(ClassPathEntry* entry, jint *manifest_size, TRAPS) {
-    return NULL;
+  static void set_has_app_classes() {
+    _has_app_classes = true;
   }
-  static void process_jar_manifest(ClassPathEntry* entry, bool check_for_duplicates) {}
+  static void set_has_platform_classes() {
+    _has_platform_classes = true;
+  }
 #endif
 };
 
--- a/src/hotspot/share/classfile/klassFactory.hpp	Wed Dec 06 15:14:13 2017 -0800
+++ b/src/hotspot/share/classfile/klassFactory.hpp	Sat Dec 02 06:51:10 2017 +0100
@@ -25,7 +25,7 @@
 #ifndef SHARE_VM_CLASSFILE_KLASSFACTORY_HPP
 #define SHARE_VM_CLASSFILE_KLASSFACTORY_HPP
 
-#include "memory/allocation.inline.hpp"
+#include "memory/allocation.hpp"
 #include "runtime/handles.hpp"
 
 class ClassFileStream;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/classfile/sharedClassUtil.cpp	Sat Dec 02 06:51:10 2017 +0100
@@ -0,0 +1,251 @@
+/*
+ * Copyright (c) 2014, 2017, 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 "classfile/classLoader.hpp"
+#include "classfile/classLoaderExt.hpp"
+#include "classfile/dictionary.hpp"
+#include "classfile/javaClasses.hpp"
+#include "classfile/sharedClassUtil.hpp"
+#include "classfile/stringTable.hpp"
+#include "classfile/symbolTable.hpp"
+#include "classfile/systemDictionary.hpp"
+#include "classfile/systemDictionaryShared.hpp"
+#include "memory/filemap.hpp"
+#include "memory/metadataFactory.hpp"
+#include "memory/resourceArea.hpp"
+#include "oops/instanceKlass.hpp"
+#include "runtime/arguments.hpp"
+#include "runtime/java.hpp"
+#include "runtime/os.hpp"
+
+class ManifestStream: public ResourceObj {
+  private:
+  u1*   _buffer_start; // Buffer bottom
+  u1*   _buffer_end;   // Buffer top (one past last element)
+  u1*   _current;      // Current buffer position
+
+ public:
+  // Constructor
+  ManifestStream(u1* buffer, int length) : _buffer_start(buffer),
+                                           _current(buffer) {
+    _buffer_end = buffer + length;
+  }
+
+  static bool is_attr(u1* attr, const char* name) {
+    return strncmp((const char*)attr, name, strlen(name)) == 0;
+  }
+
+  static char* copy_attr(u1* value, size_t len) {
+    char* buf = NEW_RESOURCE_ARRAY(char, len + 1);
+    strncpy(buf, (char*)value, len);
+    buf[len] = 0;
+    return buf;
+  }
+
+  // The return value indicates if the JAR is signed or not
+  bool check_is_signed() {
+    u1* attr = _current;
+    bool isSigned = false;
+    while (_current < _buffer_end) {
+      if (*_current == '\n') {
+        *_current = '\0';
+        u1* value = (u1*)strchr((char*)attr, ':');
+        if (value != NULL) {
+          assert(*(value+1) == ' ', "Unrecognized format" );
+          if (strstr((char*)attr, "-Digest") != NULL) {
+            isSigned = true;
+            break;
+          }
+        }
+        *_current = '\n'; // restore
+        attr = _current + 1;
+      }
+      _current ++;
+    }
+    return isSigned;
+  }
+};
+
+void SharedPathsMiscInfoExt::print_path(outputStream* out, int type, const char* path) {
+  switch(type) {
+  case APP:
+    ClassLoader::trace_class_path("Expecting -Djava.class.path=", path);
+    break;
+  default:
+    SharedPathsMiscInfo::print_path(out, type, path);
+  }
+}
+
+bool SharedPathsMiscInfoExt::check(jint type, const char* path) {
+
+  switch (type) {
+  case APP:
+    {
+      // Prefix is OK: E.g., dump with -cp foo.jar, but run with -cp foo.jar:bar.jar
+      size_t len = strlen(path);
+      const char *appcp = Arguments::get_appclasspath();
+      assert(appcp != NULL, "NULL app classpath");
+      size_t appcp_len = strlen(appcp);
+      if (appcp_len < len) {
+        return fail("Run time APP classpath is shorter than the one at dump time: ", appcp);
+      }
+      ResourceMark rm;
+      char* tmp_path;
+      if (len == appcp_len) {
+        tmp_path = (char*)appcp;
+      } else {
+        tmp_path = NEW_RESOURCE_ARRAY(char, len + 1);
+        strncpy(tmp_path, appcp, len);
+        tmp_path[len] = 0;
+      }
+      if (os::file_name_strcmp(path, tmp_path) != 0) {
+        return fail("[APP classpath mismatch, actual: -Djava.class.path=", appcp);
+      }
+      if (appcp[len] != '\0' && appcp[len] != os::path_separator()[0]) {
+        return fail("Dump time APP classpath is not a proper prefix of run time APP classpath: ", appcp);
+      }
+    }
+    break;
+  default:
+    return SharedPathsMiscInfo::check(type, path);
+  }
+
+  return true;
+}
+
+void SharedClassUtil::update_shared_classpath(ClassPathEntry *cpe, SharedClassPathEntry* e, TRAPS) {
+  ClassLoaderData* loader_data = ClassLoaderData::the_null_class_loader_data();
+  SharedClassPathEntryExt* ent = (SharedClassPathEntryExt*)e;
+  ResourceMark rm(THREAD);
+  jint manifest_size;
+  bool isSigned;
+
+  if (cpe->is_jar_file()) {
+    char* manifest = ClassLoaderExt::read_manifest(cpe, &manifest_size, CHECK);
+    if (manifest != NULL) {
+      ManifestStream* stream = new ManifestStream((u1*)manifest,
+                                                  manifest_size);
+      isSigned = stream->check_is_signed();
+      if (isSigned) {
+        ent->_is_signed = true;
+      } else {
+        // Copy the manifest into the shared archive
+        manifest = ClassLoaderExt::read_raw_manifest(cpe, &manifest_size, CHECK);
+        Array<u1>* buf = MetadataFactory::new_array<u1>(loader_data,
+                                                        manifest_size,
+                                                        THREAD);
+        char* p = (char*)(buf->data());
+        memcpy(p, manifest, manifest_size);
+        ent->set_manifest(buf);
+        ent->_is_signed = false;
+      }
+    }
+  }
+}
+
+void SharedClassUtil::initialize(TRAPS) {
+  if (UseSharedSpaces) {
+    int size = FileMapInfo::get_number_of_share_classpaths();
+    if (size > 0) {
+      SystemDictionaryShared::allocate_shared_data_arrays(size, THREAD);
+      if (!DumpSharedSpaces) {
+        FileMapHeaderExt* header = (FileMapHeaderExt*)FileMapInfo::current_info()->header();
+        ClassLoaderExt::init_paths_start_index(header->_app_paths_start_index);
+      }
+    }
+  }
+
+  if (DumpSharedSpaces) {
+    if (SharedArchiveConfigFile) {
+      read_extra_data(SharedArchiveConfigFile, THREAD);
+    }
+  }
+}
+
+void SharedClassUtil::read_extra_data(const char* filename, TRAPS) {
+  HashtableTextDump reader(filename);
+  reader.check_version("VERSION: 1.0");
+
+  while (reader.remain() > 0) {
+    int utf8_length;
+    int prefix_type = reader.scan_prefix(&utf8_length);
+    ResourceMark rm(THREAD);
+    char* utf8_buffer = NEW_RESOURCE_ARRAY(char, utf8_length);
+    reader.get_utf8(utf8_buffer, utf8_length);
+
+    if (prefix_type == HashtableTextDump::SymbolPrefix) {
+      SymbolTable::new_symbol(utf8_buffer, utf8_length, THREAD);
+    } else{
+      assert(prefix_type == HashtableTextDump::StringPrefix, "Sanity");
+      utf8_buffer[utf8_length] = '\0';
+      oop s = StringTable::intern(utf8_buffer, THREAD);
+    }
+  }
+}
+
+bool SharedClassUtil::is_classpath_entry_signed(int classpath_index) {
+  assert(classpath_index >= 0, "Sanity");
+  SharedClassPathEntryExt* ent = (SharedClassPathEntryExt*)
+    FileMapInfo::shared_classpath(classpath_index);
+  return ent->_is_signed;
+}
+
+void FileMapHeaderExt::populate(FileMapInfo* mapinfo, size_t alignment) {
+  FileMapInfo::FileMapHeader::populate(mapinfo, alignment);
+
+  ClassLoaderExt::finalize_shared_paths_misc_info();
+  _app_paths_start_index = ClassLoaderExt::app_paths_start_index();
+
+  _verify_local = BytecodeVerificationLocal;
+  _verify_remote = BytecodeVerificationRemote;
+  _has_platform_or_app_classes = ClassLoaderExt::has_platform_or_app_classes();
+}
+
+bool FileMapHeaderExt::validate() {
+  if (UseAppCDS) {
+    const char* prop = Arguments::get_property("java.system.class.loader");
+    if (prop != NULL) {
+      warning("UseAppCDS is disabled because the java.system.class.loader property is specified (value = \"%s\"). "
+              "To enable UseAppCDS, this property must be not be set", prop);
+      UseAppCDS = false;
+    }
+  }
+
+  if (!FileMapInfo::FileMapHeader::validate()) {
+    return false;
+  }
+
+  // For backwards compatibility, we don't check the verification setting
+  // if the archive only contains system classes.
+  if (_has_platform_or_app_classes &&
+      ((!_verify_local && BytecodeVerificationLocal) ||
+       (!_verify_remote && BytecodeVerificationRemote))) {
+    FileMapInfo::fail_continue("The shared archive file was created with less restrictive "
+                  "verification setting than the current setting.");
+    return false;
+  }
+
+  return true;
+}
--- a/src/hotspot/share/classfile/sharedClassUtil.hpp	Wed Dec 06 15:14:13 2017 -0800
+++ b/src/hotspot/share/classfile/sharedClassUtil.hpp	Sat Dec 02 06:51:10 2017 +0100
@@ -27,37 +27,108 @@
 
 #include "classfile/sharedPathsMiscInfo.hpp"
 #include "memory/filemap.hpp"
+#include "classfile/classLoaderExt.hpp"
+#include "classfile/dictionary.hpp"
+#include "classfile/systemDictionaryShared.hpp"
+#include "oops/klass.hpp"
+
+class FileMapHeaderExt: public FileMapInfo::FileMapHeader {
+public:
+  jshort _app_paths_start_index;    // Index of first app classpath entry
+  bool   _verify_local;             // BytecodeVerificationLocal setting
+  bool   _verify_remote;            // BytecodeVerificationRemote setting
+  bool   _has_platform_or_app_classes;          // Archive contains app classes
+
+  FileMapHeaderExt() {
+    _has_platform_or_app_classes = true;
+  }
+  virtual void populate(FileMapInfo* mapinfo, size_t alignment);
+  virtual bool validate();
+};
+
+// In addition to SharedPathsMiscInfo, the following information is also stored
+//
+//
+// + The value of Arguments::get_appclasspath() used during dumping.
+//
+class SharedPathsMiscInfoExt : public SharedPathsMiscInfo {
+private:
+  int   _app_offset;
+public:
+  enum {
+    APP       = 5
+  };
+
+  virtual const char* type_name(int type) {
+    switch (type) {
+    case APP:     return "APP";
+    default:      return SharedPathsMiscInfo::type_name(type);
+    }
+  }
+
+  virtual void print_path(outputStream* out, int type, const char* path);
+
+  SharedPathsMiscInfoExt() : SharedPathsMiscInfo() {
+    _app_offset = 0;
+  }
+  SharedPathsMiscInfoExt(char* buf, int size) : SharedPathsMiscInfo(buf, size) {
+    _app_offset = 0;
+  }
+
+  virtual bool check(jint type, const char* path);
+
+  void add_app_classpath(const char* path) {
+    add_path(path, APP);
+  }
+
+  void record_app_offset() {
+    _app_offset = get_used_bytes();
+  }
+  void pop_app() {
+    _cur_ptr = _buf_start + _app_offset;
+    write_jint(0);
+  }
+};
+
+class SharedClassPathEntryExt: public SharedClassPathEntry {
+public:
+  //Maniest attributes
+  bool _is_signed;
+  void set_manifest(Array<u1>* manifest) {
+    _manifest = manifest;
+  }
+};
 
 class SharedClassUtil : AllStatic {
 public:
-
   static SharedPathsMiscInfo* allocate_shared_paths_misc_info() {
-    return new SharedPathsMiscInfo();
+    return new SharedPathsMiscInfoExt();
   }
 
   static SharedPathsMiscInfo* allocate_shared_paths_misc_info(char* buf, int size) {
-    return new SharedPathsMiscInfo(buf, size);
+    return new SharedPathsMiscInfoExt(buf, size);
   }
 
   static FileMapInfo::FileMapHeader* allocate_file_map_header() {
-    return new FileMapInfo::FileMapHeader();
+    return new FileMapHeaderExt();
   }
 
   static size_t file_map_header_size() {
-    return sizeof(FileMapInfo::FileMapHeader);
+    return sizeof(FileMapHeaderExt);
   }
 
   static size_t shared_class_path_entry_size() {
-    return sizeof(SharedClassPathEntry);
+    return sizeof(SharedClassPathEntryExt);
   }
 
-  static void update_shared_classpath(ClassPathEntry *cpe,
-                                      SharedClassPathEntry* ent, TRAPS) {}
-  static void initialize(TRAPS) {}
+  static void update_shared_classpath(ClassPathEntry *cpe, SharedClassPathEntry* ent, TRAPS);
+  static void initialize(TRAPS);
 
-  inline static bool is_shared_boot_class(Klass* klass) {
-    return (klass->_shared_class_path_index >= 0);
-  }
+private:
+  static void read_extra_data(const char* filename, TRAPS);
+
+public:
+  static bool is_classpath_entry_signed(int classpath_index);
 };
 
 #endif // SHARE_VM_CLASSFILE_SHAREDCLASSUTIL_HPP
--- a/src/hotspot/share/classfile/sharedPathsMiscInfo.cpp	Wed Dec 06 15:14:13 2017 -0800
+++ b/src/hotspot/share/classfile/sharedPathsMiscInfo.cpp	Sat Dec 02 06:51:10 2017 +0100
@@ -34,6 +34,18 @@
 #include "runtime/arguments.hpp"
 #include "utilities/ostream.hpp"
 
+SharedPathsMiscInfo::SharedPathsMiscInfo() {
+  _buf_size = INITIAL_BUF_SIZE;
+  _cur_ptr = _buf_start = NEW_C_HEAP_ARRAY(char, _buf_size, mtClass);
+  _allocated = true;
+}
+
+SharedPathsMiscInfo::~SharedPathsMiscInfo() {
+  if (_allocated) {
+    FREE_C_HEAP_ARRAY(char, _buf_start);
+  }
+}
+
 void SharedPathsMiscInfo::add_path(const char* path, int type) {
   log_info(class, path)("type=%s ", type_name(type));
   ClassLoader::trace_class_path("add misc shared path ", path);
@@ -127,7 +139,8 @@
 bool SharedPathsMiscInfo::check(jint type, const char* path) {
   switch (type) {
   case BOOT:
-    if (os::file_name_strcmp(path, Arguments::get_sysclasspath()) != 0) {
+    // In the future we should perform the check based on the content of the mapped archive.
+    if (UseAppCDS && os::file_name_strcmp(path, Arguments::get_sysclasspath()) != 0) {
       return fail("[BOOT classpath mismatch, actual =", Arguments::get_sysclasspath());
     }
     break;
--- a/src/hotspot/share/classfile/sharedPathsMiscInfo.hpp	Wed Dec 06 15:14:13 2017 -0800
+++ b/src/hotspot/share/classfile/sharedPathsMiscInfo.hpp	Sat Dec 02 06:51:10 2017 +0100
@@ -74,11 +74,7 @@
     INITIAL_BUF_SIZE = 128
   };
   // This constructor is used when creating the misc information (during dump)
-  SharedPathsMiscInfo() {
-    _buf_size = INITIAL_BUF_SIZE;
-    _cur_ptr = _buf_start = NEW_C_HEAP_ARRAY(char, _buf_size, mtClass);
-    _allocated = true;
-  }
+  SharedPathsMiscInfo();
   // This constructor is used when validating the misc info (during run time)
   SharedPathsMiscInfo(char *buff, int size) {
     _cur_ptr = _buf_start = buff;
@@ -86,11 +82,8 @@
     _buf_size = size;
     _allocated = false;
   }
-  ~SharedPathsMiscInfo() {
-    if (_allocated) {
-      FREE_C_HEAP_ARRAY(char, _buf_start);
-    }
-  }
+  ~SharedPathsMiscInfo();
+
   int get_used_bytes() {
     return _cur_ptr - _buf_start;
   }
--- a/src/hotspot/share/classfile/stringTable.hpp	Wed Dec 06 15:14:13 2017 -0800
+++ b/src/hotspot/share/classfile/stringTable.hpp	Sat Dec 02 06:51:10 2017 +0100
@@ -25,7 +25,7 @@
 #ifndef SHARE_VM_CLASSFILE_STRINGTABLE_HPP
 #define SHARE_VM_CLASSFILE_STRINGTABLE_HPP
 
-#include "memory/allocation.inline.hpp"
+#include "memory/allocation.hpp"
 #include "utilities/hashtable.hpp"
 
 template <class T, class N> class CompactHashtable;
--- a/src/hotspot/share/classfile/symbolTable.hpp	Wed Dec 06 15:14:13 2017 -0800
+++ b/src/hotspot/share/classfile/symbolTable.hpp	Sat Dec 02 06:51:10 2017 +0100
@@ -25,7 +25,7 @@
 #ifndef SHARE_VM_CLASSFILE_SYMBOLTABLE_HPP
 #define SHARE_VM_CLASSFILE_SYMBOLTABLE_HPP
 
-#include "memory/allocation.inline.hpp"
+#include "memory/allocation.hpp"
 #include "oops/symbol.hpp"
 #include "utilities/hashtable.hpp"
 
--- a/src/hotspot/share/classfile/systemDictionary.cpp	Wed Dec 06 15:14:13 2017 -0800
+++ b/src/hotspot/share/classfile/systemDictionary.cpp	Sat Dec 02 06:51:10 2017 +0100
@@ -1087,7 +1087,7 @@
 #if INCLUDE_CDS
   ResourceMark rm(THREAD);
   if (DumpSharedSpaces && !class_loader.is_null() &&
-      !ArgumentsExt::using_AppCDS() && strcmp(class_name->as_C_string(), "Unnamed") != 0) {
+      !UseAppCDS && strcmp(class_name->as_C_string(), "Unnamed") != 0) {
     // If AppCDS is not enabled, don't define the class at dump time (except for the "Unnamed"
     // class, which is used by MethodHandles).
     THROW_MSG_NULL(vmSymbols::java_lang_ClassNotFoundException(), class_name->as_C_string());
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/classfile/systemDictionaryShared.cpp	Sat Dec 02 06:51:10 2017 +0100
@@ -0,0 +1,1086 @@
+/*
+ * Copyright (c) 2014, 2017, 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 "classfile/classFileStream.hpp"
+#include "classfile/classListParser.hpp"
+#include "classfile/classLoader.hpp"
+#include "classfile/classLoaderData.inline.hpp"
+#include "classfile/classLoaderExt.hpp"
+#include "classfile/compactHashtable.inline.hpp"
+#include "classfile/dictionary.hpp"
+#include "classfile/javaClasses.hpp"
+#include "classfile/sharedClassUtil.hpp"
+#include "classfile/symbolTable.hpp"
+#include "classfile/systemDictionary.hpp"
+#include "classfile/systemDictionaryShared.hpp"
+#include "classfile/verificationType.hpp"
+#include "classfile/vmSymbols.hpp"
+#include "logging/log.hpp"
+#include "memory/allocation.hpp"
+#include "memory/filemap.hpp"
+#include "memory/metadataFactory.hpp"
+#include "memory/metaspaceClosure.hpp"
+#include "memory/oopFactory.hpp"
+#include "memory/resourceArea.hpp"
+#include "oops/instanceKlass.hpp"
+#include "oops/klass.inline.hpp"
+#include "oops/objArrayOop.inline.hpp"
+#include "oops/oop.inline.hpp"
+#include "runtime/java.hpp"
+#include "runtime/javaCalls.hpp"
+#include "runtime/mutexLocker.hpp"
+#include "utilities/hashtable.inline.hpp"
+#include "utilities/stringUtils.hpp"
+
+
+objArrayOop SystemDictionaryShared::_shared_protection_domains  =  NULL;
+objArrayOop SystemDictionaryShared::_shared_jar_urls            =  NULL;
+objArrayOop SystemDictionaryShared::_shared_jar_manifests       =  NULL;
+
+static Mutex* SharedDictionary_lock = NULL;
+
+void SystemDictionaryShared::initialize(TRAPS) {
+  if (_java_system_loader != NULL) {
+    SharedDictionary_lock = new Mutex(Mutex::leaf, "SharedDictionary_lock", true);
+
+    // These classes need to be initialized before calling get_shared_jar_manifest(), etc.
+    SystemDictionary::ByteArrayInputStream_klass()->initialize(CHECK);
+    SystemDictionary::File_klass()->initialize(CHECK);
+    SystemDictionary::Jar_Manifest_klass()->initialize(CHECK);
+    SystemDictionary::CodeSource_klass()->initialize(CHECK);
+  }
+}
+
+oop SystemDictionaryShared::shared_protection_domain(int index) {
+  return _shared_protection_domains->obj_at(index);
+}
+
+oop SystemDictionaryShared::shared_jar_url(int index) {
+  return _shared_jar_urls->obj_at(index);
+}
+
+oop SystemDictionaryShared::shared_jar_manifest(int index) {
+  return _shared_jar_manifests->obj_at(index);
+}
+
+
+Handle SystemDictionaryShared::get_shared_jar_manifest(int shared_path_index, TRAPS) {
+  Handle empty;
+  Handle manifest ;
+  if (shared_jar_manifest(shared_path_index) == NULL) {
+    SharedClassPathEntryExt* ent = (SharedClassPathEntryExt*)FileMapInfo::shared_classpath(shared_path_index);
+    long size = ent->manifest_size();
+    if (size <= 0) {
+      return empty; // No manifest - return NULL handle
+    }
+
+    // ByteArrayInputStream bais = new ByteArrayInputStream(buf);
+    InstanceKlass* bais_klass = SystemDictionary::ByteArrayInputStream_klass();
+    Handle bais = bais_klass->allocate_instance_handle(CHECK_(empty));
+    {
+      const char* src = ent->manifest();
+      assert(src != NULL, "No Manifest data");
+      typeArrayOop buf = oopFactory::new_byteArray(size, CHECK_(empty));
+      typeArrayHandle bufhandle(THREAD, buf);
+      char* dst = (char*)(buf->byte_at_addr(0));
+      memcpy(dst, src, (size_t)size);
+
+      JavaValue result(T_VOID);
+      JavaCalls::call_special(&result, bais, bais_klass,
+                              vmSymbols::object_initializer_name(),
+                              vmSymbols::byte_array_void_signature(),
+                              bufhandle, CHECK_(empty));
+    }
+
+    // manifest = new Manifest(bais)
+    InstanceKlass* manifest_klass = SystemDictionary::Jar_Manifest_klass();
+    manifest = manifest_klass->allocate_instance_handle(CHECK_(empty));
+    {
+      JavaValue result(T_VOID);
+      JavaCalls::call_special(&result, manifest, manifest_klass,
+                              vmSymbols::object_initializer_name(),
+                              vmSymbols::input_stream_void_signature(),
+                              bais, CHECK_(empty));
+    }
+    atomic_set_shared_jar_manifest(shared_path_index, manifest());
+  }
+
+  manifest = Handle(THREAD, shared_jar_manifest(shared_path_index));
+  assert(manifest.not_null(), "sanity");
+  return manifest;
+}
+
+Handle SystemDictionaryShared::get_shared_jar_url(int shared_path_index, TRAPS) {
+  Handle url_h;
+  if (shared_jar_url(shared_path_index) == NULL) {
+    JavaValue result(T_OBJECT);
+    const char* path = FileMapInfo::shared_classpath_name(shared_path_index);
+    Handle path_string = java_lang_String::create_from_str(path, CHECK_(url_h));
+    Klass* classLoaders_klass =
+        SystemDictionary::jdk_internal_loader_ClassLoaders_klass();
+        JavaCalls::call_static(&result, classLoaders_klass,
+                               vmSymbols::toFileURL_name(),
+                               vmSymbols::toFileURL_signature(),
+                               path_string, CHECK_(url_h));
+
+    atomic_set_shared_jar_url(shared_path_index, (oop)result.get_jobject());
+  }
+
+  url_h = Handle(THREAD, shared_jar_url(shared_path_index));
+  assert(url_h.not_null(), "sanity");
+  return url_h;
+}
+
+Handle SystemDictionaryShared::get_package_name(Symbol* class_name, TRAPS) {
+  ResourceMark rm(THREAD);
+  Handle pkgname_string;
+  char* pkgname = (char*) ClassLoader::package_from_name((const char*) class_name->as_C_string());
+  if (pkgname != NULL) { // Package prefix found
+    StringUtils::replace_no_expand(pkgname, "/", ".");
+    pkgname_string = java_lang_String::create_from_str(pkgname,
+                                                       CHECK_(pkgname_string));
+  }
+  return pkgname_string;
+}
+
+// Define Package for shared app classes from JAR file and also checks for
+// package sealing (all done in Java code)
+// See http://docs.oracle.com/javase/tutorial/deployment/jar/sealman.html
+void SystemDictionaryShared::define_shared_package(Symbol*  class_name,
+                                                   Handle class_loader,
+                                                   Handle manifest,
+                                                   Handle url,
+                                                   TRAPS) {
+  assert(class_loader == _java_system_loader, "unexpected class loader");
+  // get_package_name() returns a NULL handle if the class is in unnamed package
+  Handle pkgname_string = get_package_name(class_name, CHECK);
+  if (pkgname_string.not_null()) {
+    Klass* app_classLoader_klass = SystemDictionary::jdk_internal_loader_ClassLoaders_AppClassLoader_klass();
+    JavaValue result(T_OBJECT);
+    JavaCallArguments args(3);
+    args.set_receiver(class_loader);
+    args.push_oop(pkgname_string);
+    args.push_oop(manifest);
+    args.push_oop(url);
+    JavaCalls::call_virtual(&result, app_classLoader_klass,
+                            vmSymbols::defineOrCheckPackage_name(),
+                            vmSymbols::defineOrCheckPackage_signature(),
+                            &args,
+                            CHECK);
+  }
+}
+
+// Define Package for shared app/platform classes from named module
+void SystemDictionaryShared::define_shared_package(Symbol* class_name,
+                                                   Handle class_loader,
+                                                   ModuleEntry* mod_entry,
+                                                   TRAPS) {
+  assert(mod_entry != NULL, "module_entry should not be NULL");
+  Handle module_handle(THREAD, mod_entry->module());
+
+  Handle pkg_name = get_package_name(class_name, CHECK);
+  assert(pkg_name.not_null(), "Package should not be null for class in named module");
+
+  Klass* classLoader_klass;
+  if (SystemDictionary::is_system_class_loader(class_loader())) {
+    classLoader_klass = SystemDictionary::jdk_internal_loader_ClassLoaders_AppClassLoader_klass();
+  } else {
+    assert(SystemDictionary::is_platform_class_loader(class_loader()), "unexpected classloader");
+    classLoader_klass = SystemDictionary::jdk_internal_loader_ClassLoaders_PlatformClassLoader_klass();
+  }
+
+  JavaValue result(T_OBJECT);
+  JavaCallArguments args(2);
+  args.set_receiver(class_loader);
+  args.push_oop(pkg_name);
+  args.push_oop(module_handle);
+  JavaCalls::call_virtual(&result, classLoader_klass,
+                          vmSymbols::definePackage_name(),
+                          vmSymbols::definePackage_signature(),
+                          &args,
+                          CHECK);
+}
+
+// Get the ProtectionDomain associated with the CodeSource from the classloader.
+Handle SystemDictionaryShared::get_protection_domain_from_classloader(Handle class_loader,
+                                                                      Handle url, TRAPS) {
+  // CodeSource cs = new CodeSource(url, null);
+  InstanceKlass* cs_klass = SystemDictionary::CodeSource_klass();
+  Handle cs = cs_klass->allocate_instance_handle(CHECK_NH);
+  JavaValue void_result(T_VOID);
+  JavaCalls::call_special(&void_result, cs, cs_klass,
+                          vmSymbols::object_initializer_name(),
+                          vmSymbols::url_code_signer_array_void_signature(),
+                          url, Handle(), CHECK_NH);
+
+  // protection_domain = SecureClassLoader.getProtectionDomain(cs);
+  Klass* secureClassLoader_klass = SystemDictionary::SecureClassLoader_klass();
+  JavaValue obj_result(T_OBJECT);
+  JavaCalls::call_virtual(&obj_result, class_loader, secureClassLoader_klass,
+                          vmSymbols::getProtectionDomain_name(),
+                          vmSymbols::getProtectionDomain_signature(),
+                          cs, CHECK_NH);
+  return Handle(THREAD, (oop)obj_result.get_jobject());
+}
+
+// Returns the ProtectionDomain associated with the JAR file identified by the url.
+Handle SystemDictionaryShared::get_shared_protection_domain(Handle class_loader,
+                                                            int shared_path_index,
+                                                            Handle url,
+                                                            TRAPS) {
+  Handle protection_domain;
+  if (shared_protection_domain(shared_path_index) == NULL) {
+    Handle pd = get_protection_domain_from_classloader(class_loader, url, THREAD);
+    atomic_set_shared_protection_domain(shared_path_index, pd());
+  }
+
+  // Acquire from the cache because if another thread beats the current one to
+  // set the shared protection_domain and the atomic_set fails, the current thread
+  // needs to get the updated protection_domain from the cache.
+  protection_domain = Handle(THREAD, shared_protection_domain(shared_path_index));
+  assert(protection_domain.not_null(), "sanity");
+  return protection_domain;
+}
+
+// Returns the ProtectionDomain associated with the moduleEntry.
+Handle SystemDictionaryShared::get_shared_protection_domain(Handle class_loader,
+                                                            ModuleEntry* mod, TRAPS) {
+  ClassLoaderData *loader_data = mod->loader_data();
+  Handle protection_domain;
+  if (mod->shared_protection_domain() == NULL) {
+    Symbol* location = mod->location();
+    if (location != NULL) {
+      Handle url_string = java_lang_String::create_from_symbol(
+                                 location, CHECK_(protection_domain));
+      JavaValue result(T_OBJECT);
+      Klass* classLoaders_klass =
+        SystemDictionary::jdk_internal_loader_ClassLoaders_klass();
+        JavaCalls::call_static(&result, classLoaders_klass, vmSymbols::toFileURL_name(),
+                               vmSymbols::toFileURL_signature(),
+                               url_string, CHECK_(protection_domain));
+      Handle url = Handle(THREAD, (oop)result.get_jobject());
+
+      Handle pd = get_protection_domain_from_classloader(class_loader, url, THREAD);
+      mod->set_shared_protection_domain(loader_data, pd);
+    }
+  }
+
+  protection_domain = Handle(THREAD, mod->shared_protection_domain());
+  assert(protection_domain.not_null(), "sanity");
+  return protection_domain;
+}
+
+// Initializes the java.lang.Package and java.security.ProtectionDomain objects associated with
+// the given InstanceKlass.
+// Returns the ProtectionDomain for the InstanceKlass.
+Handle SystemDictionaryShared::init_security_info(Handle class_loader, InstanceKlass* ik, TRAPS) {
+  Handle pd;
+
+  if (ik != NULL) {
+    int index = ik->shared_classpath_index();
+    assert(index >= 0, "Sanity");
+    SharedClassPathEntryExt* ent =
+            (SharedClassPathEntryExt*)FileMapInfo::shared_classpath(index);
+    Symbol* class_name = ik->name();
+
+    if (ent->is_modules_image()) {
+      // For shared app/platform classes originated from the run-time image:
+      //   The ProtectionDomains are cached in the corresponding ModuleEntries
+      //   for fast access by the VM.
+      ResourceMark rm;
+      ClassLoaderData *loader_data =
+                ClassLoaderData::class_loader_data(class_loader());
+      PackageEntryTable* pkgEntryTable = loader_data->packages();
+      TempNewSymbol pkg_name = InstanceKlass::package_from_name(class_name, CHECK_(pd));
+      if (pkg_name != NULL) {
+        PackageEntry* pkg_entry = pkgEntryTable->lookup_only(pkg_name);
+        if (pkg_entry != NULL) {
+          ModuleEntry* mod_entry = pkg_entry->module();
+          pd = get_shared_protection_domain(class_loader, mod_entry, THREAD);
+          define_shared_package(class_name, class_loader, mod_entry, CHECK_(pd));
+        }
+      }
+    } else {
+      // For shared app/platform classes originated from JAR files on the class path:
+      //   Each of the 3 SystemDictionaryShared::_shared_xxx arrays has the same length
+      //   as the shared classpath table in the shared archive (see
+      //   FileMap::_classpath_entry_table in filemap.hpp for details).
+      //
+      //   If a shared InstanceKlass k is loaded from the class path, let
+      //
+      //     index = k->shared_classpath_index():
+      //
+      //   FileMap::_classpath_entry_table[index] identifies the JAR file that contains k.
+      //
+      //   k's protection domain is:
+      //
+      //     ProtectionDomain pd = _shared_protection_domains[index];
+      //
+      //   and k's Package is initialized using
+      //
+      //     manifest = _shared_jar_manifests[index];
+      //     url = _shared_jar_urls[index];
+      //     define_shared_package(class_name, class_loader, manifest, url, CHECK_(pd));
+      //
+      //   Note that if an element of these 3 _shared_xxx arrays is NULL, it will be initialized by
+      //   the corresponding SystemDictionaryShared::get_shared_xxx() function.
+      Handle manifest = get_shared_jar_manifest(index, CHECK_(pd));
+      Handle url = get_shared_jar_url(index, CHECK_(pd));
+      define_shared_package(class_name, class_loader, manifest, url, CHECK_(pd));
+      pd = get_shared_protection_domain(class_loader, index, url, CHECK_(pd));
+    }
+  }
+  return pd;
+}
+
+// Currently AppCDS only archives classes from the run-time image, the
+// -Xbootclasspath/a path, and the class path. The following rules need to be
+// revised when AppCDS is changed to archive classes from other code sources
+// in the future, for example the module path (specified by -p).
+//
+// Check if a shared class can be loaded by the specific classloader. Following
+// are the "visible" archived classes for different classloaders.
+//
+// NULL classloader:
+//   - see SystemDictionary::is_shared_class_visible()
+// Platform classloader:
+//   - Module class from "modules" jimage. ModuleEntry must be defined in the
+//     classloader.
+// App Classloader:
+//   - Module class from "modules" jimage. ModuleEntry must be defined in the
+//     classloader.
+//   - Class from -cp. The class must have no PackageEntry defined in any of the
+//     boot/platform/app classloader, or must be in the unnamed module defined in the
+//     AppClassLoader.
+bool SystemDictionaryShared::is_shared_class_visible_for_classloader(
+                                                     InstanceKlass* ik,
+                                                     Handle class_loader,
+                                                     const char* pkg_string,
+                                                     Symbol* pkg_name,
+                                                     PackageEntry* pkg_entry,
+                                                     ModuleEntry* mod_entry,
+                                                     TRAPS) {
+  assert(class_loader.not_null(), "Class loader should not be NULL");
+  assert(Universe::is_module_initialized(), "Module system is not initialized");
+
+  int path_index = ik->shared_classpath_index();
+  SharedClassPathEntry* ent =
+            (SharedClassPathEntry*)FileMapInfo::shared_classpath(path_index);
+
+  if (SystemDictionary::is_platform_class_loader(class_loader())) {
+    assert(ent != NULL, "shared class for PlatformClassLoader should have valid SharedClassPathEntry");
+    // The PlatformClassLoader can only load archived class originated from the
+    // run-time image. The class' PackageEntry/ModuleEntry must be
+    // defined by the PlatformClassLoader.
+    if (mod_entry != NULL) {
+      // PackageEntry/ModuleEntry is found in the classloader. Check if the
+      // ModuleEntry's location agrees with the archived class' origination.
+      if (ent->is_modules_image() && mod_entry->location()->starts_with("jrt:")) {
+        return true; // Module class from the "modules" jimage
+      }
+    }
+  } else if (SystemDictionary::is_system_class_loader(class_loader())) {
+    assert(ent != NULL, "shared class for system loader should have valid SharedClassPathEntry");
+    if (pkg_string == NULL) {
+      // The archived class is in the unnamed package. Currently, the boot image
+      // does not contain any class in the unnamed package.
+      assert(!ent->is_modules_image(), "Class in the unnamed package must be from the classpath");
+      if (path_index >= ClassLoaderExt::app_paths_start_index()) {
+        return true;
+      }
+    } else {
+      // Check if this is from a PackageEntry/ModuleEntry defined in the AppClassloader.
+      if (pkg_entry == NULL) {
+        // It's not guaranteed that the class is from the classpath if the
+        // PackageEntry cannot be found from the AppClassloader. Need to check
+        // the boot and platform classloader as well.
+        if (get_package_entry(pkg_name, ClassLoaderData::class_loader_data_or_null(SystemDictionary::java_platform_loader())) == NULL &&
+            get_package_entry(pkg_name, ClassLoaderData::the_null_class_loader_data()) == NULL) {
+          // The PackageEntry is not defined in any of the boot/platform/app classloaders.
+          // The archived class must from -cp path and not from the run-time image.
+          if (!ent->is_modules_image() && path_index >= ClassLoaderExt::app_paths_start_index()) {
+            return true;
+          }
+        }
+      } else if (mod_entry != NULL) {
+        // The package/module is defined in the AppClassLoader. Currently we only
+        // support archiving application module class from the run-time image.
+        // Packages from the -cp path are in the unnamed_module.
+        if ((ent->is_modules_image() && mod_entry->location()->starts_with("jrt:")) ||
+            (pkg_entry->in_unnamed_module() && path_index >= ClassLoaderExt::app_paths_start_index())) {
+          DEBUG_ONLY( \
+            ClassLoaderData* loader_data = class_loader_data(class_loader); \
+            if (pkg_entry->in_unnamed_module()) \
+              assert(mod_entry == loader_data->unnamed_module(), "the unnamed module is not defined in the classloader");)
+
+          return true;
+        }
+      }
+    }
+  } else {
+    // TEMP: if a shared class can be found by a custom loader, consider it visible now.
+    // FIXME: is this actually correct?
+    return true;
+  }
+  return false;
+}
+
+// The following stack shows how this code is reached:
+//
+//   [0] SystemDictionaryShared::find_or_load_shared_class()
+//   [1] JVM_FindLoadedClass
+//   [2] java.lang.ClassLoader.findLoadedClass0()
+//   [3] java.lang.ClassLoader.findLoadedClass()
+//   [4] java.lang.ClassLoader.loadClass()
+//   [5] jdk.internal.loader.ClassLoaders$AppClassLoader_klass.loadClass()
+//
+// Because AppCDS supports only the PlatformClassLoader and AppClassLoader, we make the following
+// assumptions (based on the JDK 8.0 source code):
+//
+// [a] these two loaders use the default implementation of
+//     ClassLoader.loadClass(String name, boolean resolve), which
+// [b] calls findLoadedClass(name), immediately followed by parent.loadClass(),
+//     immediately followed by findClass(name).
+// [c] If the requested class is a shared class of the current class loader, parent.loadClass()
+//     always returns null, and
+// [d] if AppCDS is not enabled, the class would be loaded by findClass() by decoding it from a
+//     JAR file and then parsed.
+//
+// Given these assumptions, we intercept the findLoadedClass() call to invoke
+// SystemDictionaryShared::find_or_load_shared_class() to load the shared class from
+// the archive. The reasons are:
+//
+// + Because AppCDS is a commercial feature, we want to hide the implementation. There
+//   is currently no easy way to hide Java code, so we did it with native code.
+// + Start-up is improved because we avoid decoding the JAR file, and avoid delegating
+//   to the parent (since we know the parent will not find this class).
+//
+// NOTE: there's a lot of assumption about the Java code. If any of that change, this
+// needs to be redesigned.
+//
+// An alternative is to modify the Java code of AppClassLoader.loadClass().
+//
+InstanceKlass* SystemDictionaryShared::find_or_load_shared_class(
+                 Symbol* name, Handle class_loader, TRAPS) {
+  if (DumpSharedSpaces) {
+    return NULL;
+  }
+
+  InstanceKlass* k = NULL;
+  if (shared_dictionary() != NULL &&
+      UseAppCDS && (SystemDictionary::is_system_class_loader(class_loader()) ||
+                    SystemDictionary::is_platform_class_loader(class_loader()))) {
+
+    // Fix for 4474172; see evaluation for more details
+    class_loader = Handle(
+      THREAD, java_lang_ClassLoader::non_reflection_class_loader(class_loader()));
+    ClassLoaderData *loader_data = register_loader(class_loader, CHECK_NULL);
+    Dictionary* dictionary = loader_data->dictionary();
+
+    unsigned int d_hash = dictionary->compute_hash(name);
+
+    bool DoObjectLock = true;
+    if (is_parallelCapable(class_loader)) {
+      DoObjectLock = false;
+    }
+
+    // Make sure we are synchronized on the class loader before we proceed
+    //
+    // Note: currently, find_or_load_shared_class is called only from
+    // JVM_FindLoadedClass and used for PlatformClassLoader and AppClassLoader,
+    // which are parallel-capable loaders, so this lock is NOT taken.
+    Handle lockObject = compute_loader_lock_object(class_loader, THREAD);
+    check_loader_lock_contention(lockObject, THREAD);
+    ObjectLocker ol(lockObject, THREAD, DoObjectLock);
+
+    {
+      MutexLocker mu(SystemDictionary_lock, THREAD);
+      Klass* check = find_class(d_hash, name, dictionary);
+      if (check != NULL) {
+        return InstanceKlass::cast(check);
+      }
+    }
+
+    k = load_shared_class_for_builtin_loader(name, class_loader, THREAD);
+    if (k != NULL) {
+      define_instance_class(k, CHECK_NULL);
+    }
+  }
+
+  return k;
+}
+
+InstanceKlass* SystemDictionaryShared::load_shared_class_for_builtin_loader(
+                 Symbol* class_name, Handle class_loader, TRAPS) {
+  assert(UseAppCDS && shared_dictionary() != NULL, "already checked");
+  Klass* k = shared_dictionary()->find_class_for_builtin_loader(class_name);
+
+  if (k != NULL) {
+    InstanceKlass* ik = InstanceKlass::cast(k);
+    if ((ik->is_shared_app_class() &&
+         SystemDictionary::is_system_class_loader(class_loader()))  ||
+        (ik->is_shared_platform_class() &&
+         SystemDictionary::is_platform_class_loader(class_loader()))) {
+      Handle protection_domain =
+        SystemDictionaryShared::init_security_info(class_loader, ik, CHECK_NULL);
+      return load_shared_class(ik, class_loader, protection_domain, THREAD);
+    }
+  }
+
+  return NULL;
+}
+
+void SystemDictionaryShared::oops_do(OopClosure* f) {
+  f->do_oop((oop*)&_shared_protection_domains);
+  f->do_oop((oop*)&_shared_jar_urls);
+  f->do_oop((oop*)&_shared_jar_manifests);
+}
+
+void SystemDictionaryShared::allocate_shared_protection_domain_array(int size, TRAPS) {
+  if (_shared_protection_domains == NULL) {
+    _shared_protection_domains = oopFactory::new_objArray(
+        SystemDictionary::ProtectionDomain_klass(), size, CHECK);
+  }
+}
+
+void SystemDictionaryShared::allocate_shared_jar_url_array(int size, TRAPS) {
+  if (_shared_jar_urls == NULL) {
+    _shared_jar_urls = oopFactory::new_objArray(
+        SystemDictionary::URL_klass(), size, CHECK);
+  }
+}
+
+void SystemDictionaryShared::allocate_shared_jar_manifest_array(int size, TRAPS) {
+  if (_shared_jar_manifests == NULL) {
+    _shared_jar_manifests = oopFactory::new_objArray(
+        SystemDictionary::Jar_Manifest_klass(), size, CHECK);
+  }
+}
+
+void SystemDictionaryShared::allocate_shared_data_arrays(int size, TRAPS) {
+  allocate_shared_protection_domain_array(size, CHECK);
+  allocate_shared_jar_url_array(size, CHECK);
+  allocate_shared_jar_manifest_array(size, CHECK);
+}
+
+
+InstanceKlass* SystemDictionaryShared::lookup_from_stream(const Symbol* class_name,
+                                                          Handle class_loader,
+                                                          Handle protection_domain,
+                                                          const ClassFileStream* cfs,
+                                                          TRAPS) {
+  if (!UseAppCDS || shared_dictionary() == NULL) {
+    return NULL;
+  }
+  if (class_name == NULL) {  // don't do this for anonymous classes
+    return NULL;
+  }
+  if (class_loader.is_null() ||
+      SystemDictionary::is_system_class_loader(class_loader()) ||
+      SystemDictionary::is_platform_class_loader(class_loader())) {
+    // This function is called for loading only UNREGISTERED classes.
+    // Do nothing for the BUILTIN loaders.
+    return NULL;
+  }
+
+  ClassLoaderData* loader_data = ClassLoaderData::class_loader_data(class_loader());
+  Klass* k;
+
+  { // UNREGISTERED loader
+    if (!shared_dictionary()->class_exists_for_unregistered_loader(class_name)) {
+      // No classes of this name for unregistered loaders.
+      return NULL;
+    }
+
+    int clsfile_size  = cfs->length();
+    int clsfile_crc32 = ClassLoader::crc32(0, (const char*)cfs->buffer(), cfs->length());
+
+    k = shared_dictionary()->find_class_for_unregistered_loader(class_name,
+                                                                clsfile_size, clsfile_crc32);
+  }
+
+  if (k == NULL) { // not archived
+    return NULL;
+  }
+
+  return acquire_class_for_current_thread(InstanceKlass::cast(k), class_loader,
+                                          protection_domain, THREAD);
+}
+
+InstanceKlass* SystemDictionaryShared::acquire_class_for_current_thread(
+                   InstanceKlass *ik,
+                   Handle class_loader,
+                   Handle protection_domain,
+                   TRAPS) {
+  ClassLoaderData* loader_data = ClassLoaderData::class_loader_data(class_loader());
+
+  {
+    MutexLocker mu(SharedDictionary_lock, THREAD);
+    if (ik->class_loader_data() != NULL) {
+      //    ik is already loaded (by this loader or by a different loader)
+      // or ik is being loaded by a different thread (by this loader or by a different loader)
+      return NULL;
+    }
+
+    // No other thread has acquired this yet, so give it to *this thread*
+    ik->set_class_loader_data(loader_data);
+  }
+
+  // No longer holding SharedDictionary_lock
+  // No need to lock, as <ik> can be held only by a single thread.
+  loader_data->add_class(ik);
+
+  // Load and check super/interfaces, restore unsharable info
+  InstanceKlass* shared_klass = load_shared_class(ik, class_loader, protection_domain, THREAD);
+  if (shared_klass == NULL || HAS_PENDING_EXCEPTION) {
+    // TODO: clean up <ik> so it can be used again
+    return NULL;
+  }
+
+  return shared_klass;
+}
+
+bool SystemDictionaryShared::add_non_builtin_klass(Symbol* name, ClassLoaderData* loader_data,
+                                                   InstanceKlass* k,
+                                                   TRAPS) {
+  assert(DumpSharedSpaces, "only when dumping");
+  assert(UseAppCDS && boot_loader_dictionary() != NULL, "must be");
+
+  if (boot_loader_dictionary()->add_non_builtin_klass(name, loader_data, k)) {
+    MutexLocker mu_r(Compile_lock, THREAD); // not really necessary, but add_to_hierarchy asserts this.
+    add_to_hierarchy(k, CHECK_0);
+    return true;
+  }
+  return false;
+}
+
+// This function is called to resolve the super/interfaces of shared classes for
+// non-built-in loaders. E.g., ChildClass in the below example
+// where "super:" (and optionally "interface:") have been specified.
+//
+// java/lang/Object id: 0
+// Interface   id: 2 super: 0 source: cust.jar
+// ChildClass  id: 4 super: 0 interfaces: 2 source: cust.jar
+Klass* SystemDictionaryShared::dump_time_resolve_super_or_fail(
+    Symbol* child_name, Symbol* class_name, Handle class_loader,
+    Handle protection_domain, bool is_superclass, TRAPS) {
+
+  assert(DumpSharedSpaces, "only when dumping");
+
+  ClassListParser* parser = ClassListParser::instance();
+  if (parser == NULL) {
+    // We're still loading the well-known classes, before the ClassListParser is created.
+    return NULL;
+  }
+  if (child_name->equals(parser->current_class_name())) {
+    // When this function is called, all the numbered super and interface types
+    // must have already been loaded. Hence this function is never recursively called.
+    if (is_superclass) {
+      return parser->lookup_super_for_current_class(class_name);
+    } else {
+      return parser->lookup_interface_for_current_class(class_name);
+    }
+  } else {
+    // The VM is not trying to resolve a super type of parser->current_class_name().
+    // Instead, it's resolving an error class (because parser->current_class_name() has
+    // failed parsing or verification). Don't do anything here.
+    return NULL;
+  }
+}
+
+struct SharedMiscInfo {
+  Klass* _klass;
+  int _clsfile_size;
+  int _clsfile_crc32;
+};
+
+static GrowableArray<SharedMiscInfo>* misc_info_array = NULL;
+
+void SystemDictionaryShared::set_shared_class_misc_info(Klass* k, ClassFileStream* cfs) {
+  assert(DumpSharedSpaces, "only when dumping");
+  int clsfile_size  = cfs->length();
+  int clsfile_crc32 = ClassLoader::crc32(0, (const char*)cfs->buffer(), cfs->length());
+
+  if (misc_info_array == NULL) {
+    misc_info_array = new (ResourceObj::C_HEAP, mtClass) GrowableArray<SharedMiscInfo>(20, /*c heap*/ true);
+  }
+
+  SharedMiscInfo misc_info;
+  DEBUG_ONLY({
+      for (int i=0; i<misc_info_array->length(); i++) {
+        misc_info = misc_info_array->at(i);
+        assert(misc_info._klass != k, "cannot call set_shared_class_misc_info twice for the same class");
+      }
+    });
+
+  misc_info._klass = k;
+  misc_info._clsfile_size = clsfile_size;
+  misc_info._clsfile_crc32 = clsfile_crc32;
+
+  misc_info_array->append(misc_info);
+}
+
+void SystemDictionaryShared::init_shared_dictionary_entry(Klass* k, DictionaryEntry* ent) {
+  SharedDictionaryEntry* entry = (SharedDictionaryEntry*)ent;
+  entry->_id = -1;
+  entry->_clsfile_size = -1;
+  entry->_clsfile_crc32 = -1;
+  entry->_verifier_constraints = NULL;
+  entry->_verifier_constraint_flags = NULL;
+
+  if (misc_info_array != NULL) {
+    for (int i=0; i<misc_info_array->length(); i++) {
+      SharedMiscInfo misc_info = misc_info_array->at(i);
+      if (misc_info._klass == k) {
+        entry->_clsfile_size = misc_info._clsfile_size;
+        entry->_clsfile_crc32 = misc_info._clsfile_crc32;
+        misc_info_array->remove_at(i);
+        return;
+      }
+    }
+  }
+}
+
+bool SystemDictionaryShared::add_verification_constraint(Klass* k, Symbol* name,
+         Symbol* from_name, bool from_field_is_protected, bool from_is_array, bool from_is_object) {
+  assert(DumpSharedSpaces, "called at dump time only");
+
+  // Skip anonymous classes, which are not archived as they are not in
+  // dictionary (see assert_no_anonymoys_classes_in_dictionaries() in
+  // VM_PopulateDumpSharedSpace::doit()).
+  if (k->class_loader_data()->is_anonymous()) {
+    return true; // anonymous classes are not archived, skip
+  }
+
+  SharedDictionaryEntry* entry = ((SharedDictionary*)(k->class_loader_data()->dictionary()))->find_entry_for(k);
+  ResourceMark rm;
+  // Lambda classes are not archived and will be regenerated at runtime.
+  if (entry == NULL && strstr(k->name()->as_C_string(), "Lambda$") != NULL) {
+    return true;
+  }
+  assert(entry != NULL, "class should be in dictionary before being verified");
+  entry->add_verification_constraint(name, from_name, from_field_is_protected,
+                                     from_is_array, from_is_object);
+  if (entry->is_builtin()) {
+    // For builtin class loaders, we can try to complete the verification check at dump time,
+    // because we can resolve all the constraint classes.
+    return false;
+  } else {
+    // For non-builtin class loaders, we cannot complete the verification check at dump time,
+    // because at dump time we don't know how to resolve classes for such loaders.
+    return true;
+  }
+}
+
+void SystemDictionaryShared::finalize_verification_constraints() {
+  boot_loader_dictionary()->finalize_verification_constraints();
+}
+
+void SystemDictionaryShared::check_verification_constraints(InstanceKlass* klass,
+                                                             TRAPS) {
+  assert(!DumpSharedSpaces && UseSharedSpaces, "called at run time with CDS enabled only");
+  SharedDictionaryEntry* entry = shared_dictionary()->find_entry_for(klass);
+  assert(entry != NULL, "call this only for shared classes");
+  entry->check_verification_constraints(klass, THREAD);
+}
+
+SharedDictionaryEntry* SharedDictionary::find_entry_for(Klass* klass) {
+  Symbol* class_name = klass->name();
+  unsigned int hash = compute_hash(class_name);
+  int index = hash_to_index(hash);
+
+  for (SharedDictionaryEntry* entry = bucket(index);
+                              entry != NULL;
+                              entry = entry->next()) {
+    if (entry->hash() == hash && entry->literal() == klass) {
+      return entry;
+    }
+  }
+
+  return NULL;
+}
+
+void SharedDictionary::finalize_verification_constraints() {
+  int bytes = 0, count = 0;
+  for (int index = 0; index < table_size(); index++) {
+    for (SharedDictionaryEntry *probe = bucket(index);
+                                probe != NULL;
+                               probe = probe->next()) {
+      int n = probe->finalize_verification_constraints();
+      if (n > 0) {
+        bytes += n;
+        count ++;
+      }