Merge
authorsspitsyn
Fri, 09 Sep 2016 06:44:31 +0000
changeset 41068 55c16639f2ea
parent 41067 77a87b5e001c (current diff)
parent 41066 e8c366069761 (diff)
child 41069 9f985f4ecea8
child 41071 ff13773da5f8
Merge
--- a/hotspot/src/cpu/sparc/vm/sparc.ad	Thu Sep 08 23:38:56 2016 -0700
+++ b/hotspot/src/cpu/sparc/vm/sparc.ad	Fri Sep 09 06:44:31 2016 +0000
@@ -2921,6 +2921,26 @@
     __ cmp( Rold, O7 );
   %}
 
+  // raw int cas without using tmp register for compareAndExchange
+  enc_class enc_casi_exch( iRegP mem, iRegL old, iRegL new) %{
+    Register Rmem = reg_to_register_object($mem$$reg);
+    Register Rold = reg_to_register_object($old$$reg);
+    Register Rnew = reg_to_register_object($new$$reg);
+
+    MacroAssembler _masm(&cbuf);
+    __ cas(Rmem, Rold, Rnew);
+  %}
+
+  // 64-bit cas without using tmp register for compareAndExchange
+  enc_class enc_casx_exch( iRegP mem, iRegL old, iRegL new) %{
+    Register Rmem = reg_to_register_object($mem$$reg);
+    Register Rold = reg_to_register_object($old$$reg);
+    Register Rnew = reg_to_register_object($new$$reg);
+
+    MacroAssembler _masm(&cbuf);
+    __ casx(Rmem, Rold, Rnew);
+  %}
+
   enc_class enc_lflags_ne_to_boolean( iRegI res ) %{
     Register Rres = reg_to_register_object($res$$reg);
 
@@ -7105,6 +7125,7 @@
 instruct compareAndSwapL_bool(iRegP mem_ptr, iRegL oldval, iRegL newval, iRegI res, o7RegI tmp1, flagsReg ccr ) %{
   predicate(VM_Version::supports_cx8());
   match(Set res (CompareAndSwapL mem_ptr (Binary oldval newval)));
+  match(Set res (WeakCompareAndSwapL mem_ptr (Binary oldval newval)));
   effect( USE mem_ptr, KILL ccr, KILL tmp1);
   format %{
             "MOV    $newval,O7\n\t"
@@ -7121,6 +7142,7 @@
 
 instruct compareAndSwapI_bool(iRegP mem_ptr, iRegI oldval, iRegI newval, iRegI res, o7RegI tmp1, flagsReg ccr ) %{
   match(Set res (CompareAndSwapI mem_ptr (Binary oldval newval)));
+  match(Set res (WeakCompareAndSwapI mem_ptr (Binary oldval newval)));
   effect( USE mem_ptr, KILL ccr, KILL tmp1);
   format %{
             "MOV    $newval,O7\n\t"
@@ -7139,6 +7161,7 @@
   predicate(VM_Version::supports_cx8());
 #endif
   match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval)));
+  match(Set res (WeakCompareAndSwapP mem_ptr (Binary oldval newval)));
   effect( USE mem_ptr, KILL ccr, KILL tmp1);
   format %{
             "MOV    $newval,O7\n\t"
@@ -7159,6 +7182,7 @@
 
 instruct compareAndSwapN_bool(iRegP mem_ptr, iRegN oldval, iRegN newval, iRegI res, o7RegI tmp1, flagsReg ccr ) %{
   match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval)));
+  match(Set res (WeakCompareAndSwapN mem_ptr (Binary oldval newval)));
   effect( USE mem_ptr, KILL ccr, KILL tmp1);
   format %{
             "MOV    $newval,O7\n\t"
@@ -7172,6 +7196,54 @@
   ins_pipe( long_memory_op );
 %}
 
+instruct compareAndExchangeI(iRegP mem_ptr, iRegI oldval, iRegI newval)
+%{
+  match(Set newval (CompareAndExchangeI mem_ptr (Binary oldval newval)));
+  effect( USE mem_ptr );
+
+  format %{
+            "CASA   [$mem_ptr],$oldval,$newval\t! If $oldval==[$mem_ptr] Then store $newval into [$mem_ptr] and set $newval=[$mem_ptr]\n\t"
+  %}
+  ins_encode( enc_casi_exch(mem_ptr, oldval, newval) );
+  ins_pipe( long_memory_op );
+%}
+
+instruct compareAndExchangeL(iRegP mem_ptr, iRegL oldval, iRegL newval)
+%{
+  match(Set newval (CompareAndExchangeL mem_ptr (Binary oldval newval)));
+  effect( USE mem_ptr );
+
+  format %{
+            "CASXA  [$mem_ptr],$oldval,$newval\t! If $oldval==[$mem_ptr] Then store $newval into [$mem_ptr] and set $newval=[$mem_ptr]\n\t"
+  %}
+  ins_encode( enc_casx_exch(mem_ptr, oldval, newval) );
+  ins_pipe( long_memory_op );
+%}
+
+instruct compareAndExchangeP(iRegP mem_ptr, iRegP oldval, iRegP newval)
+%{
+  match(Set newval (CompareAndExchangeP mem_ptr (Binary oldval newval)));
+  effect( USE mem_ptr );
+
+  format %{
+            "CASXA  [$mem_ptr],$oldval,$newval\t! If $oldval==[$mem_ptr] Then store $newval into [$mem_ptr] and set $newval=[$mem_ptr]\n\t"
+  %}
+  ins_encode( enc_casx_exch(mem_ptr, oldval, newval) );
+  ins_pipe( long_memory_op );
+%}
+
+instruct compareAndExchangeN(iRegP mem_ptr, iRegN oldval, iRegN newval)
+%{
+  match(Set newval (CompareAndExchangeN mem_ptr (Binary oldval newval)));
+  effect( USE mem_ptr );
+
+  format %{
+            "CASA   [$mem_ptr],$oldval,$newval\t! If $oldval==[$mem_ptr] Then store $newval into [$mem_ptr] and set $newval=[$mem_ptr]\n\t"
+  %}
+  ins_encode( enc_casi_exch(mem_ptr, oldval, newval) );
+  ins_pipe( long_memory_op );
+%}
+
 instruct xchgI( memory mem, iRegI newval) %{
   match(Set newval (GetAndSetI mem newval));
   format %{ "SWAP  [$mem],$newval" %}
--- a/hotspot/src/cpu/x86/vm/globals_x86.hpp	Thu Sep 08 23:38:56 2016 -0700
+++ b/hotspot/src/cpu/x86/vm/globals_x86.hpp	Fri Sep 09 06:44:31 2016 +0000
@@ -65,10 +65,10 @@
 #ifdef AMD64
 // Very large C++ stack frames using solaris-amd64 optimized builds
 // due to lack of optimization caused by C++ compiler bugs
-#define DEFAULT_STACK_SHADOW_PAGES (NOT_WIN64(20) WIN64_ONLY(6) DEBUG_ONLY(+2))
+#define DEFAULT_STACK_SHADOW_PAGES (NOT_WIN64(20) WIN64_ONLY(7) DEBUG_ONLY(+2))
 // For those clients that do not use write socket, we allow
 // the min range value to be below that of the default
-#define MIN_STACK_SHADOW_PAGES (NOT_WIN64(10) WIN64_ONLY(6) DEBUG_ONLY(+2))
+#define MIN_STACK_SHADOW_PAGES (NOT_WIN64(10) WIN64_ONLY(7) DEBUG_ONLY(+2))
 #else
 #define DEFAULT_STACK_SHADOW_PAGES (4 DEBUG_ONLY(+5))
 #define MIN_STACK_SHADOW_PAGES DEFAULT_STACK_SHADOW_PAGES
--- a/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp	Thu Sep 08 23:38:56 2016 -0700
+++ b/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp	Fri Sep 09 06:44:31 2016 +0000
@@ -8131,8 +8131,7 @@
     jmp(FALSE_LABEL);
 
     clear_vector_masking();   // closing of the stub context for programming mask registers
-  }
-  else {
+  } else {
     movl(result, len); // copy
 
     if (UseAVX == 2 && UseSSE >= 2) {
@@ -8169,8 +8168,7 @@
       bind(COMPARE_TAIL); // len is zero
       movl(len, result);
       // Fallthru to tail compare
-    }
-    else if (UseSSE42Intrinsics) {
+    } else if (UseSSE42Intrinsics) {
       // With SSE4.2, use double quad vector compare
       Label COMPARE_WIDE_VECTORS, COMPARE_TAIL;
 
@@ -10748,7 +10746,10 @@
   // save length for return
   push(len);
 
+  // 8165287: EVEX version disabled for now, needs to be refactored as
+  // it is returning incorrect results.
   if ((UseAVX > 2) && // AVX512
+    0 &&
     VM_Version::supports_avx512vlbw() &&
     VM_Version::supports_bmi2()) {
 
@@ -11067,10 +11068,11 @@
 
       bind(below_threshold);
       bind(copy_new_tail);
-      if (UseAVX > 2) {
+      if ((UseAVX > 2) &&
+        VM_Version::supports_avx512vlbw() &&
+        VM_Version::supports_bmi2()) {
         movl(tmp2, len);
-      }
-      else {
+      } else {
         movl(len, tmp2);
       }
       andl(tmp2, 0x00000007);
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/CompilerToVM.java	Thu Sep 08 23:38:56 2016 -0700
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/CompilerToVM.java	Fri Sep 09 06:44:31 2016 +0000
@@ -366,8 +366,8 @@
      * {@code exactReceiver}.
      *
      * @param caller the caller or context type used to perform access checks
-     * @return the link-time resolved method (might be abstract) or {@code 0} if it can not be
-     *         linked
+     * @return the link-time resolved method (might be abstract) or {@code null} if it is either a
+     *         signature polymorphic method or can not be linked.
      */
     native HotSpotResolvedJavaMethodImpl resolveMethod(HotSpotResolvedObjectTypeImpl exactReceiver, HotSpotResolvedJavaMethodImpl method, HotSpotResolvedObjectTypeImpl caller);
 
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotConstantPool.java	Thu Sep 08 23:38:56 2016 -0700
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotConstantPool.java	Fri Sep 09 06:44:31 2016 +0000
@@ -722,7 +722,7 @@
     /**
      * Determines if {@code type} contains signature polymorphic methods.
      */
-    private static boolean isSignaturePolymorphicHolder(final HotSpotResolvedObjectTypeImpl type) {
+    static boolean isSignaturePolymorphicHolder(final ResolvedJavaType type) {
         String name = type.getName();
         if (signaturePolymorphicHolders == null) {
             signaturePolymorphicHolders = compilerToVM().getSignaturePolymorphicHolders();
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java	Thu Sep 08 23:38:56 2016 -0700
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java	Fri Sep 09 06:44:31 2016 +0000
@@ -24,6 +24,7 @@
 
 import static java.util.Objects.requireNonNull;
 import static jdk.vm.ci.hotspot.CompilerToVM.compilerToVM;
+import static jdk.vm.ci.hotspot.HotSpotConstantPool.isSignaturePolymorphicHolder;
 import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime;
 import static jdk.vm.ci.hotspot.HotSpotVMConfig.config;
 import static jdk.vm.ci.hotspot.UnsafeAccess.UNSAFE;
@@ -426,7 +427,7 @@
             // Methods can only be resolved against concrete types
             return null;
         }
-        if (method.isConcrete() && method.getDeclaringClass().equals(this) && method.isPublic()) {
+        if (method.isConcrete() && method.getDeclaringClass().equals(this) && method.isPublic() && !isSignaturePolymorphicHolder(method.getDeclaringClass())) {
             return method;
         }
         if (!method.getDeclaringClass().isAssignableFrom(this)) {
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ResolvedJavaType.java	Thu Sep 08 23:38:56 2016 -0700
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ResolvedJavaType.java	Fri Sep 09 06:44:31 2016 +0000
@@ -209,8 +209,8 @@
      *
      * @param method the method to select the implementation of
      * @param callerType the caller or context type used to perform access checks
-     * @return the method that would be selected at runtime (might be abstract) or {@code null} if
-     *         it can not be resolved
+     * @return the link-time resolved method (might be abstract) or {@code null} if it is either a
+     *         signature polymorphic method or can not be linked.
      */
     ResolvedJavaMethod resolveMethod(ResolvedJavaMethod method, ResolvedJavaType callerType);
 
--- a/hotspot/src/os/linux/vm/os_linux.cpp	Thu Sep 08 23:38:56 2016 -0700
+++ b/hotspot/src/os/linux/vm/os_linux.cpp	Fri Sep 09 06:44:31 2016 +0000
@@ -2875,7 +2875,7 @@
                               // in the library.
   const size_t BitsPerCLong = sizeof(long) * CHAR_BIT;
 
-  size_t cpu_num = os::active_processor_count();
+  size_t cpu_num = processor_count();
   size_t cpu_map_size = NCPUS / BitsPerCLong;
   size_t cpu_map_valid_size =
     MIN2((cpu_num + BitsPerCLong - 1) / BitsPerCLong, cpu_map_size);
--- a/hotspot/src/os/windows/vm/os_windows.cpp	Thu Sep 08 23:38:56 2016 -0700
+++ b/hotspot/src/os/windows/vm/os_windows.cpp	Fri Sep 09 06:44:31 2016 +0000
@@ -2504,13 +2504,15 @@
   // It write enables the page immediately after protecting it
   // so just return.
   if (exception_code == EXCEPTION_ACCESS_VIOLATION) {
-    JavaThread* thread = (JavaThread*) t;
-    PEXCEPTION_RECORD exceptionRecord = exceptionInfo->ExceptionRecord;
-    address addr = (address) exceptionRecord->ExceptionInformation[1];
-    if (os::is_memory_serialize_page(thread, addr)) {
-      // Block current thread until the memory serialize page permission restored.
-      os::block_on_serialize_page_trap();
-      return EXCEPTION_CONTINUE_EXECUTION;
+    if (t != NULL && t->is_Java_thread()) {
+      JavaThread* thread = (JavaThread*) t;
+      PEXCEPTION_RECORD exceptionRecord = exceptionInfo->ExceptionRecord;
+      address addr = (address) exceptionRecord->ExceptionInformation[1];
+      if (os::is_memory_serialize_page(thread, addr)) {
+        // Block current thread until the memory serialize page permission restored.
+        os::block_on_serialize_page_trap();
+        return EXCEPTION_CONTINUE_EXECUTION;
+      }
     }
   }
 
@@ -2564,7 +2566,7 @@
       }
 #endif
       if (thread->stack_guards_enabled()) {
-        if (_thread_in_Java) {
+        if (in_java) {
           frame fr;
           PEXCEPTION_RECORD exceptionRecord = exceptionInfo->ExceptionRecord;
           address addr = (address) exceptionRecord->ExceptionInformation[1];
@@ -2576,6 +2578,7 @@
         // Yellow zone violation.  The o/s has unprotected the first yellow
         // zone page for us.  Note:  must call disable_stack_yellow_zone to
         // update the enabled status, even if the zone contains only one page.
+        assert(thread->thread_state() != _thread_in_vm, "Undersized StackShadowPages");
         thread->disable_stack_yellow_reserved_zone();
         // If not in java code, return and hope for the best.
         return in_java
@@ -3793,6 +3796,11 @@
   GlobalMemoryStatusEx(&ms);
   _physical_memory = ms.ullTotalPhys;
 
+  if (FLAG_IS_DEFAULT(MaxRAM)) {
+    // Adjust MaxRAM according to the maximum virtual address space available.
+    FLAG_SET_DEFAULT(MaxRAM, MIN2(MaxRAM, (uint64_t) ms.ullTotalVirtual));
+  }
+
   OSVERSIONINFOEX oi;
   oi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
   GetVersionEx((OSVERSIONINFO*)&oi);
--- a/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp	Thu Sep 08 23:38:56 2016 -0700
+++ b/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp	Fri Sep 09 06:44:31 2016 +0000
@@ -2410,6 +2410,15 @@
 #endif // INCLUDE_ALL_GCS
 
   if (x->is_volatile() && os::is_MP()) __ membar_acquire();
+
+  /* Normalize boolean value returned by unsafe operation, i.e., value  != 0 ? value = true : value false. */
+  if (type == T_BOOLEAN) {
+    LabelObj* equalZeroLabel = new LabelObj();
+    __ cmp(lir_cond_equal, value, 0);
+    __ branch(lir_cond_equal, T_BOOLEAN, equalZeroLabel->label());
+    __ move(LIR_OprFact::intConst(1), value);
+    __ branch_destination(equalZeroLabel->label());
+  }
 }
 
 
--- a/hotspot/src/share/vm/c1/c1_Runtime1.cpp	Thu Sep 08 23:38:56 2016 -0700
+++ b/hotspot/src/share/vm/c1/c1_Runtime1.cpp	Fri Sep 09 06:44:31 2016 +0000
@@ -576,9 +576,8 @@
     // normal bytecode execution.
     thread->clear_exception_oop_and_pc();
 
-    Handle original_exception(thread, exception());
-
-    continuation = SharedRuntime::compute_compiled_exc_handler(nm, pc, exception, false, false);
+    bool recursive_exception = false;
+    continuation = SharedRuntime::compute_compiled_exc_handler(nm, pc, exception, false, false, recursive_exception);
     // If an exception was thrown during exception dispatch, the exception oop may have changed
     thread->set_exception_oop(exception());
     thread->set_exception_pc(pc);
@@ -586,8 +585,9 @@
     // the exception cache is used only by non-implicit exceptions
     // Update the exception cache only when there didn't happen
     // another exception during the computation of the compiled
-    // exception handler.
-    if (continuation != NULL && original_exception() == exception()) {
+    // exception handler. Checking for exception oop equality is not
+    // sufficient because some exceptions are pre-allocated and reused.
+    if (continuation != NULL && !recursive_exception) {
       nm->add_handler_for_exception_and_pc(exception, pc, continuation);
     }
   }
--- a/hotspot/src/share/vm/classfile/classFileParser.cpp	Thu Sep 08 23:38:56 2016 -0700
+++ b/hotspot/src/share/vm/classfile/classFileParser.cpp	Fri Sep 09 06:44:31 2016 +0000
@@ -5407,6 +5407,59 @@
   debug_only(ik->verify();)
 }
 
+// For an anonymous class that is in the unnamed package, move it to its host class's
+// package by prepending its host class's package name to its class name and setting
+// its _class_name field.
+void ClassFileParser::prepend_host_package_name(const InstanceKlass* host_klass, TRAPS) {
+  ResourceMark rm(THREAD);
+  assert(strrchr(_class_name->as_C_string(), '/') == NULL,
+         "Anonymous class should not be in a package");
+  const char* host_pkg_name =
+    ClassLoader::package_from_name(host_klass->name()->as_C_string(), NULL);
+
+  if (host_pkg_name != NULL) {
+    size_t host_pkg_len = strlen(host_pkg_name);
+    int class_name_len = _class_name->utf8_length();
+    char* new_anon_name =
+      NEW_RESOURCE_ARRAY(char, host_pkg_len + 1 + class_name_len);
+    // Copy host package name and trailing /.
+    strncpy(new_anon_name, host_pkg_name, host_pkg_len);
+    new_anon_name[host_pkg_len] = '/';
+    // Append anonymous class name. The anonymous class name can contain odd
+    // characters.  So, do a strncpy instead of using sprintf("%s...").
+    strncpy(new_anon_name + host_pkg_len + 1, (char *)_class_name->base(), class_name_len);
+
+    // Create a symbol and update the anonymous class name.
+    _class_name = SymbolTable::new_symbol(new_anon_name,
+                                          (int)host_pkg_len + 1 + class_name_len,
+                                          CHECK);
+  }
+}
+
+// If the host class and the anonymous class are in the same package then do
+// nothing.  If the anonymous class is in the unnamed package then move it to its
+// host's package.  If the classes are in different packages then throw an IAE
+// exception.
+void ClassFileParser::fix_anonymous_class_name(TRAPS) {
+  assert(_host_klass != NULL, "Expected an anonymous class");
+
+  const jbyte* anon_last_slash = UTF8::strrchr(_class_name->base(),
+                                               _class_name->utf8_length(), '/');
+  if (anon_last_slash == NULL) {  // Unnamed package
+    prepend_host_package_name(_host_klass, CHECK);
+  } else {
+    if (!InstanceKlass::is_same_class_package(_host_klass->class_loader(),
+                                              _host_klass->name(),
+                                              _host_klass->class_loader(),
+                                              _class_name)) {
+      ResourceMark rm(THREAD);
+      THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
+        err_msg("Host class %s and anonymous class %s are in different packages",
+        _host_klass->name()->as_C_string(), _class_name->as_C_string()));
+    }
+  }
+}
+
 static bool relax_format_check_for(ClassLoaderData* loader_data) {
   bool trusted = (loader_data->is_the_null_class_loader_data() ||
                   SystemDictionary::is_platform_class_loader(loader_data->class_loader()));
@@ -5422,7 +5475,7 @@
                                  Symbol* name,
                                  ClassLoaderData* loader_data,
                                  Handle protection_domain,
-                                 const Klass* host_klass,
+                                 const InstanceKlass* host_klass,
                                  GrowableArray<Handle>* cp_patches,
                                  Publicity pub_level,
                                  TRAPS) :
@@ -5697,6 +5750,13 @@
     return;
   }
 
+  // if this is an anonymous class fix up its name if it's in the unnamed
+  // package.  Otherwise, throw IAE if it is in a different package than
+  // its host class.
+  if (_host_klass != NULL) {
+    fix_anonymous_class_name(CHECK);
+  }
+
   // Verification prevents us from creating names with dots in them, this
   // asserts that that's the case.
   assert(is_internal_format(_class_name), "external class name format used internally");
--- a/hotspot/src/share/vm/classfile/classFileParser.hpp	Thu Sep 08 23:38:56 2016 -0700
+++ b/hotspot/src/share/vm/classfile/classFileParser.hpp	Fri Sep 09 06:44:31 2016 +0000
@@ -79,7 +79,7 @@
   const Symbol* _requested_name;
   Symbol* _class_name;
   mutable ClassLoaderData* _loader_data;
-  const Klass* _host_klass;
+  const InstanceKlass* _host_klass;
   GrowableArray<Handle>* _cp_patches; // overrides for CP entries
 
   // Metadata created before the instance klass is created.  Must be deallocated
@@ -155,6 +155,9 @@
                                   ConstantPool* cp,
                                   TRAPS);
 
+  void prepend_host_package_name(const InstanceKlass* host_klass, TRAPS);
+  void fix_anonymous_class_name(TRAPS);
+
   void fill_instance_klass(InstanceKlass* ik, bool cf_changed_in_CFLH, TRAPS);
   void set_klass(InstanceKlass* instance);
 
@@ -474,7 +477,7 @@
                   Symbol* name,
                   ClassLoaderData* loader_data,
                   Handle protection_domain,
-                  const Klass* host_klass,
+                  const InstanceKlass* host_klass,
                   GrowableArray<Handle>* cp_patches,
                   Publicity pub_level,
                   TRAPS);
@@ -500,7 +503,7 @@
   bool is_anonymous() const { return _host_klass != NULL; }
   bool is_interface() const { return _access_flags.is_interface(); }
 
-  const Klass* host_klass() const { return _host_klass; }
+  const InstanceKlass* host_klass() const { return _host_klass; }
   const GrowableArray<Handle>* cp_patches() const { return _cp_patches; }
   ClassLoaderData* loader_data() const { return _loader_data; }
   const Symbol* class_name() const { return _class_name; }
--- a/hotspot/src/share/vm/classfile/classLoaderData.cpp	Thu Sep 08 23:38:56 2016 -0700
+++ b/hotspot/src/share/vm/classfile/classLoaderData.cpp	Fri Sep 09 06:44:31 2016 +0000
@@ -966,7 +966,7 @@
   // Klasses to delete.
   bool walk_all_metadata = clean_previous_versions &&
                            JvmtiExport::has_redefined_a_class() &&
-                           InstanceKlass::has_previous_versions();
+                           InstanceKlass::has_previous_versions_and_reset();
   MetadataOnStackMark md_on_stack(walk_all_metadata);
 
   // Save previous _unloading pointer for CMS which may add to unloading list before
--- a/hotspot/src/share/vm/classfile/klassFactory.cpp	Thu Sep 08 23:38:56 2016 -0700
+++ b/hotspot/src/share/vm/classfile/klassFactory.cpp	Fri Sep 09 06:44:31 2016 +0000
@@ -94,7 +94,7 @@
                                                      Symbol* name,
                                                      ClassLoaderData* loader_data,
                                                      Handle protection_domain,
-                                                     const Klass* host_klass,
+                                                     const InstanceKlass* host_klass,
                                                      GrowableArray<Handle>* cp_patches,
                                                      TRAPS) {
 
--- a/hotspot/src/share/vm/classfile/klassFactory.hpp	Thu Sep 08 23:38:56 2016 -0700
+++ b/hotspot/src/share/vm/classfile/klassFactory.hpp	Fri Sep 09 06:44:31 2016 +0000
@@ -72,7 +72,7 @@
                                                 Symbol* name,
                                                 ClassLoaderData* loader_data,
                                                 Handle protection_domain,
-                                                const Klass* host_klass,
+                                                const InstanceKlass* host_klass,
                                                 GrowableArray<Handle>* cp_patches,
                                                 TRAPS);
 };
--- a/hotspot/src/share/vm/classfile/systemDictionary.cpp	Thu Sep 08 23:38:56 2016 -0700
+++ b/hotspot/src/share/vm/classfile/systemDictionary.cpp	Fri Sep 09 06:44:31 2016 +0000
@@ -1027,7 +1027,7 @@
                                       Handle class_loader,
                                       Handle protection_domain,
                                       ClassFileStream* st,
-                                      const Klass* host_klass,
+                                      const InstanceKlass* host_klass,
                                       GrowableArray<Handle>* cp_patches,
                                       TRAPS) {
 
--- a/hotspot/src/share/vm/classfile/systemDictionary.hpp	Thu Sep 08 23:38:56 2016 -0700
+++ b/hotspot/src/share/vm/classfile/systemDictionary.hpp	Fri Sep 09 06:44:31 2016 +0000
@@ -299,7 +299,7 @@
                              Handle class_loader,
                              Handle protection_domain,
                              ClassFileStream* st,
-                             const Klass* host_klass,
+                             const InstanceKlass* host_klass,
                              GrowableArray<Handle>* cp_patches,
                              TRAPS);
 
--- a/hotspot/src/share/vm/classfile/verifier.cpp	Thu Sep 08 23:38:56 2016 -0700
+++ b/hotspot/src/share/vm/classfile/verifier.cpp	Fri Sep 09 06:44:31 2016 +0000
@@ -2786,7 +2786,7 @@
       // direct interface relative to the host class
       have_imr_indirect = (have_imr_indirect &&
                            !is_same_or_direct_interface(
-                             InstanceKlass::cast(current_class()->host_klass()),
+                             current_class()->host_klass(),
                              host_klass_type, ref_class_type));
     }
     if (!subtype) {
--- a/hotspot/src/share/vm/code/codeCache.cpp	Thu Sep 08 23:38:56 2016 -0700
+++ b/hotspot/src/share/vm/code/codeCache.cpp	Fri Sep 09 06:44:31 2016 +0000
@@ -1305,7 +1305,7 @@
     event.set_entryCount(heap->blob_count());
     event.set_methodCount(heap->nmethod_count());
     event.set_adaptorCount(heap->adapter_count());
-    event.set_unallocatedCapacity(heap->unallocated_capacity()/K);
+    event.set_unallocatedCapacity(heap->unallocated_capacity());
     event.set_fullCount(heap->full_count());
     event.commit();
   }
--- a/hotspot/src/share/vm/gc/cms/concurrentMarkSweepGeneration.cpp	Thu Sep 08 23:38:56 2016 -0700
+++ b/hotspot/src/share/vm/gc/cms/concurrentMarkSweepGeneration.cpp	Fri Sep 09 06:44:31 2016 +0000
@@ -3511,6 +3511,7 @@
                                                                   conc_workers()->active_workers(),
                                                                   Threads::number_of_non_daemon_threads());
   num_workers = conc_workers()->update_active_workers(num_workers);
+  log_info(gc,task)("Using %u workers of %u for marking", num_workers, conc_workers()->total_workers());
 
   CompactibleFreeListSpace* cms_space  = _cmsGen->cmsSpace();
 
--- a/hotspot/src/share/vm/gc/cms/parNewGeneration.cpp	Thu Sep 08 23:38:56 2016 -0700
+++ b/hotspot/src/share/vm/gc/cms/parNewGeneration.cpp	Fri Sep 09 06:44:31 2016 +0000
@@ -899,6 +899,8 @@
                                                workers->active_workers(),
                                                Threads::number_of_non_daemon_threads());
   active_workers = workers->update_active_workers(active_workers);
+  log_info(gc,task)("Using %u workers of %u for evacuation", active_workers, workers->total_workers());
+
   _old_gen = gch->old_gen();
 
   // If the next generation is too full to accommodate worst-case promotion
--- a/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp	Thu Sep 08 23:38:56 2016 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp	Fri Sep 09 06:44:31 2016 +0000
@@ -1332,6 +1332,7 @@
                                                 workers()->active_workers(),
                                                 Threads::number_of_non_daemon_threads());
       workers()->update_active_workers(n_workers);
+      log_info(gc,task)("Using %u workers of %u to rebuild remembered set", n_workers, workers()->total_workers());
 
       ParRebuildRSTask rebuild_rs_task(this);
       workers()->run_task(&rebuild_rs_task);
@@ -3068,6 +3069,7 @@
                                                                   workers()->active_workers(),
                                                                   Threads::number_of_non_daemon_threads());
     workers()->update_active_workers(active_workers);
+    log_info(gc,task)("Using %u workers of %u for evacuation", active_workers, workers()->total_workers());
 
     TraceCollectorStats tcs(g1mm()->incremental_collection_counters());
     TraceMemoryManagerStats tms(false /* fullGC */, gc_cause());
--- a/hotspot/src/share/vm/gc/g1/g1ConcurrentMark.cpp	Thu Sep 08 23:38:56 2016 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1ConcurrentMark.cpp	Fri Sep 09 06:44:31 2016 +0000
@@ -1035,6 +1035,8 @@
   // worker threads may currently exist and more may not be
   // available.
   active_workers = _parallel_workers->update_active_workers(active_workers);
+  log_info(gc, task)("Using %u workers of %u for marking", active_workers, _parallel_workers->total_workers());
+
   // Parallel task terminator is set in "set_concurrency_and_phase()"
   set_concurrency_and_phase(active_workers, true /* concurrent */);
 
--- a/hotspot/src/share/vm/gc/shared/workgroup.hpp	Thu Sep 08 23:38:56 2016 -0700
+++ b/hotspot/src/share/vm/gc/shared/workgroup.hpp	Fri Sep 09 06:44:31 2016 +0000
@@ -162,7 +162,7 @@
     _active_workers = MIN2(v, _total_workers);
     add_workers(false /* exit_on_failure */);
     assert(v != 0, "Trying to set active workers to 0");
-    log_info(gc, task)("GC Workers: using %d out of %d", _active_workers, _total_workers);
+    log_trace(gc, task)("%s: using %d out of %d workers", name(), _active_workers, _total_workers);
     return _active_workers;
   }
 
--- a/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp	Thu Sep 08 23:38:56 2016 -0700
+++ b/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp	Fri Sep 09 06:44:31 2016 +0000
@@ -576,27 +576,39 @@
   // compute auxiliary field attributes
   TosState state  = as_TosState(info.field_type());
 
-  // Put instructions on final fields are not resolved. This is required so we throw
-  // exceptions at the correct place (when the instruction is actually invoked).
+  // Resolution of put instructions on final fields is delayed. That is required so that
+  // exceptions are thrown at the correct place (when the instruction is actually invoked).
   // If we do not resolve an instruction in the current pass, leaving the put_code
   // set to zero will cause the next put instruction to the same field to reresolve.
+
+  // Resolution of put instructions to final instance fields with invalid updates (i.e.,
+  // to final instance fields with updates originating from a method different than <init>)
+  // is inhibited. A putfield instruction targeting an instance final field must throw
+  // an IllegalAccessError if the instruction is not in an instance
+  // initializer method <init>. If resolution were not inhibited, a putfield
+  // in an initializer method could be resolved in the initializer. Subsequent
+  // putfield instructions to the same field would then use cached information.
+  // As a result, those instructions would not pass through the VM. That is,
+  // checks in resolve_field_access() would not be executed for those instructions
+  // and the required IllegalAccessError would not be thrown.
   //
   // Also, we need to delay resolving getstatic and putstatic instructions until the
   // class is initialized.  This is required so that access to the static
   // field will call the initialization function every time until the class
   // is completely initialized ala. in 2.17.5 in JVM Specification.
   InstanceKlass* klass = InstanceKlass::cast(info.field_holder());
-  bool uninitialized_static = ((bytecode == Bytecodes::_getstatic || bytecode == Bytecodes::_putstatic) &&
-                               !klass->is_initialized());
-
-  Bytecodes::Code put_code = (Bytecodes::Code)0;
-  if (is_put && !info.access_flags().is_final() && !uninitialized_static) {
-    put_code = ((is_static) ? Bytecodes::_putstatic : Bytecodes::_putfield);
-  }
+  bool uninitialized_static = is_static && !klass->is_initialized();
+  bool has_initialized_final_update = info.field_holder()->major_version() >= 53 &&
+                                      info.has_initialized_final_update();
+  assert(!(has_initialized_final_update && !info.access_flags().is_final()), "Fields with initialized final updates must be final");
 
   Bytecodes::Code get_code = (Bytecodes::Code)0;
+  Bytecodes::Code put_code = (Bytecodes::Code)0;
   if (!uninitialized_static) {
     get_code = ((is_static) ? Bytecodes::_getstatic : Bytecodes::_getfield);
+    if ((is_put && !has_initialized_final_update) || !info.access_flags().is_final()) {
+      put_code = ((is_static) ? Bytecodes::_putstatic : Bytecodes::_putfield);
+    }
   }
 
   cp_cache_entry->set_field(
--- a/hotspot/src/share/vm/jvmci/jvmciCompilerToVM.cpp	Thu Sep 08 23:38:56 2016 -0700
+++ b/hotspot/src/share/vm/jvmci/jvmciCompilerToVM.cpp	Fri Sep 09 06:44:31 2016 +0000
@@ -768,6 +768,11 @@
   Symbol* h_name      = method->name();
   Symbol* h_signature = method->signature();
 
+  if (MethodHandles::is_signature_polymorphic_method(method())) {
+      // Signature polymorphic methods are already resolved, JVMCI just returns NULL in this case.
+      return NULL;
+  }
+
   LinkInfo link_info(h_resolved, h_name, h_signature, caller_klass);
   methodHandle m;
   // Only do exact lookup if receiver klass has been linked.  Otherwise,
@@ -782,7 +787,7 @@
   }
 
   if (m.is_null()) {
-    // Return NULL only if there was a problem with lookup (uninitialized class, etc.)
+    // Return NULL if there was a problem with lookup (uninitialized class, etc.)
     return NULL;
   }
 
--- a/hotspot/src/share/vm/jvmci/jvmciRuntime.cpp	Thu Sep 08 23:38:56 2016 -0700
+++ b/hotspot/src/share/vm/jvmci/jvmciRuntime.cpp	Fri Sep 09 06:44:31 2016 +0000
@@ -313,13 +313,18 @@
     // normal bytecode execution.
     thread->clear_exception_oop_and_pc();
 
-    continuation = SharedRuntime::compute_compiled_exc_handler(cm, pc, exception, false, false);
+    bool recursive_exception = false;
+    continuation = SharedRuntime::compute_compiled_exc_handler(cm, pc, exception, false, false, recursive_exception);
     // If an exception was thrown during exception dispatch, the exception oop may have changed
     thread->set_exception_oop(exception());
     thread->set_exception_pc(pc);
 
     // the exception cache is used only by non-implicit exceptions
-    if (continuation != NULL && !SharedRuntime::deopt_blob()->contains(continuation)) {
+    // Update the exception cache only when there didn't happen
+    // another exception during the computation of the compiled
+    // exception handler. Checking for exception oop equality is not
+    // sufficient because some exceptions are pre-allocated and reused.
+    if (continuation != NULL && !recursive_exception && !SharedRuntime::deopt_blob()->contains(continuation)) {
       cm->add_handler_for_exception_and_pc(exception, pc, continuation);
     }
   }
--- a/hotspot/src/share/vm/logging/logConfiguration.cpp	Thu Sep 08 23:38:56 2016 -0700
+++ b/hotspot/src/share/vm/logging/logConfiguration.cpp	Fri Sep 09 06:44:31 2016 +0000
@@ -385,6 +385,7 @@
                                            const char* decoratorstr,
                                            const char* output_options,
                                            outputStream* errstream) {
+  assert(errstream != NULL, "errstream can not be NULL");
   if (outputstr == NULL || strlen(outputstr) == 0) {
     outputstr = "stdout";
   }
--- a/hotspot/src/share/vm/oops/instanceKlass.cpp	Thu Sep 08 23:38:56 2016 -0700
+++ b/hotspot/src/share/vm/oops/instanceKlass.cpp	Fri Sep 09 06:44:31 2016 +0000
@@ -3365,88 +3365,119 @@
 
 #if INCLUDE_JVMTI
 
-// RedefineClasses() support for previous versions:
-int InstanceKlass::_previous_version_count = 0;
-
-// Purge previous versions before adding new previous versions of the class.
-void InstanceKlass::purge_previous_versions(InstanceKlass* ik) {
-  if (ik->previous_versions() != NULL) {
-    // This klass has previous versions so see what we can cleanup
-    // while it is safe to do so.
-
-    int deleted_count = 0;    // leave debugging breadcrumbs
-    int live_count = 0;
-    ClassLoaderData* loader_data = ik->class_loader_data();
-    assert(loader_data != NULL, "should never be null");
-
-    ResourceMark rm;
-    log_trace(redefine, class, iklass, purge)("%s: previous versions", ik->external_name());
-
-    // previous versions are linked together through the InstanceKlass
-    InstanceKlass* pv_node = ik->previous_versions();
-    InstanceKlass* last = ik;
-    int version = 0;
-
-    // check the previous versions list
-    for (; pv_node != NULL; ) {
-
-      ConstantPool* pvcp = pv_node->constants();
-      assert(pvcp != NULL, "cp ref was unexpectedly cleared");
-
-      if (!pvcp->on_stack()) {
-        // If the constant pool isn't on stack, none of the methods
-        // are executing.  Unlink this previous_version.
-        // The previous version InstanceKlass is on the ClassLoaderData deallocate list
-        // so will be deallocated during the next phase of class unloading.
-        log_trace(redefine, class, iklass, purge)("previous version " INTPTR_FORMAT " is dead", p2i(pv_node));
-        // For debugging purposes.
-        pv_node->set_is_scratch_class();
-        pv_node->class_loader_data()->add_to_deallocate_list(pv_node);
-        pv_node = pv_node->previous_versions();
-        last->link_previous_versions(pv_node);
-        deleted_count++;
-        version++;
-        continue;
-      } else {
-        log_trace(redefine, class, iklass, purge)("previous version " INTPTR_FORMAT " is alive", p2i(pv_node));
-        assert(pvcp->pool_holder() != NULL, "Constant pool with no holder");
-        guarantee (!loader_data->is_unloading(), "unloaded classes can't be on the stack");
-        live_count++;
-      }
-
-      // At least one method is live in this previous version.
-      // Reset dead EMCP methods not to get breakpoints.
-      // All methods are deallocated when all of the methods for this class are no
-      // longer running.
-      Array<Method*>* method_refs = pv_node->methods();
-      if (method_refs != NULL) {
-        log_trace(redefine, class, iklass, purge)("previous methods length=%d", method_refs->length());
-        for (int j = 0; j < method_refs->length(); j++) {
-          Method* method = method_refs->at(j);
-
-          if (!method->on_stack()) {
-            // no breakpoints for non-running methods
-            if (method->is_running_emcp()) {
-              method->set_running_emcp(false);
-            }
-          } else {
-            assert (method->is_obsolete() || method->is_running_emcp(),
-                    "emcp method cannot run after emcp bit is cleared");
-            log_trace(redefine, class, iklass, purge)
-              ("purge: %s(%s): prev method @%d in version @%d is alive",
-               method->name()->as_C_string(), method->signature()->as_C_string(), j, version);
+// RedefineClasses() support for previous versions
+
+// Globally, there is at least one previous version of a class to walk
+// during class unloading, which is saved because old methods in the class
+// are still running.   Otherwise the previous version list is cleaned up.
+bool InstanceKlass::_has_previous_versions = false;
+
+// Returns true if there are previous versions of a class for class
+// unloading only. Also resets the flag to false. purge_previous_version
+// will set the flag to true if there are any left, i.e., if there's any
+// work to do for next time. This is to avoid the expensive code cache
+// walk in CLDG::do_unloading().
+bool InstanceKlass::has_previous_versions_and_reset() {
+  bool ret = _has_previous_versions;
+  log_trace(redefine, class, iklass, purge)("Class unloading: has_previous_versions = %s",
+     ret ? "true" : "false");
+  _has_previous_versions = false;
+  return ret;
+}
+
+// Purge previous versions before adding new previous versions of the class and
+// during class unloading.
+void InstanceKlass::purge_previous_version_list() {
+  assert(SafepointSynchronize::is_at_safepoint(), "only called at safepoint");
+  assert(has_been_redefined(), "Should only be called for main class");
+
+  // Quick exit.
+  if (previous_versions() == NULL) {
+    return;
+  }
+
+  // This klass has previous versions so see what we can cleanup
+  // while it is safe to do so.
+
+  int deleted_count = 0;    // leave debugging breadcrumbs
+  int live_count = 0;
+  ClassLoaderData* loader_data = class_loader_data();
+  assert(loader_data != NULL, "should never be null");
+
+  ResourceMark rm;
+  log_trace(redefine, class, iklass, purge)("%s: previous versions", external_name());
+
+  // previous versions are linked together through the InstanceKlass
+  InstanceKlass* pv_node = previous_versions();
+  InstanceKlass* last = this;
+  int version = 0;
+
+  // check the previous versions list
+  for (; pv_node != NULL; ) {
+
+    ConstantPool* pvcp = pv_node->constants();
+    assert(pvcp != NULL, "cp ref was unexpectedly cleared");
+
+    if (!pvcp->on_stack()) {
+      // If the constant pool isn't on stack, none of the methods
+      // are executing.  Unlink this previous_version.
+      // The previous version InstanceKlass is on the ClassLoaderData deallocate list
+      // so will be deallocated during the next phase of class unloading.
+      log_trace(redefine, class, iklass, purge)
+        ("previous version " INTPTR_FORMAT " is dead.", p2i(pv_node));
+      // For debugging purposes.
+      pv_node->set_is_scratch_class();
+      // Unlink from previous version list.
+      assert(pv_node->class_loader_data() == loader_data, "wrong loader_data");
+      InstanceKlass* next = pv_node->previous_versions();
+      pv_node->link_previous_versions(NULL);   // point next to NULL
+      last->link_previous_versions(next);
+      // Add to the deallocate list after unlinking
+      loader_data->add_to_deallocate_list(pv_node);
+      pv_node = next;
+      deleted_count++;
+      version++;
+      continue;
+    } else {
+      log_trace(redefine, class, iklass, purge)("previous version " INTPTR_FORMAT " is alive", p2i(pv_node));
+      assert(pvcp->pool_holder() != NULL, "Constant pool with no holder");
+      guarantee (!loader_data->is_unloading(), "unloaded classes can't be on the stack");
+      live_count++;
+      // found a previous version for next time we do class unloading
+      _has_previous_versions = true;
+    }
+
+    // At least one method is live in this previous version.
+    // Reset dead EMCP methods not to get breakpoints.
+    // All methods are deallocated when all of the methods for this class are no
+    // longer running.
+    Array<Method*>* method_refs = pv_node->methods();
+    if (method_refs != NULL) {
+      log_trace(redefine, class, iklass, purge)("previous methods length=%d", method_refs->length());
+      for (int j = 0; j < method_refs->length(); j++) {
+        Method* method = method_refs->at(j);
+
+        if (!method->on_stack()) {
+          // no breakpoints for non-running methods
+          if (method->is_running_emcp()) {
+            method->set_running_emcp(false);
           }
+        } else {
+          assert (method->is_obsolete() || method->is_running_emcp(),
+                  "emcp method cannot run after emcp bit is cleared");
+          log_trace(redefine, class, iklass, purge)
+            ("purge: %s(%s): prev method @%d in version @%d is alive",
+             method->name()->as_C_string(), method->signature()->as_C_string(), j, version);
         }
       }
-      // next previous version
-      last = pv_node;
-      pv_node = pv_node->previous_versions();
-      version++;
     }
-    log_trace(redefine, class, iklass, purge)
-      ("previous version stats: live=%d, deleted=%d",
-       live_count, deleted_count);
+    // next previous version
+    last = pv_node;
+    pv_node = pv_node->previous_versions();
+    version++;
   }
+  log_trace(redefine, class, iklass, purge)
+    ("previous version stats: live=%d, deleted=%d", live_count, deleted_count);
 }
 
 void InstanceKlass::mark_newly_obsolete_methods(Array<Method*>* old_methods,
@@ -3518,8 +3549,8 @@
   log_trace(redefine, class, iklass, add)
     ("adding previous version ref for %s, EMCP_cnt=%d", scratch_class->external_name(), emcp_method_count);
 
-  // Clean out old previous versions
-  purge_previous_versions(this);
+  // Clean out old previous versions for this class
+  purge_previous_version_list();
 
   // Mark newly obsolete methods in remaining previous versions.  An EMCP method from
   // a previous redefinition may be made obsolete by this redefinition.
@@ -3536,8 +3567,6 @@
     // For debugging purposes.
     scratch_class->set_is_scratch_class();
     scratch_class->class_loader_data()->add_to_deallocate_list(scratch_class());
-    // Update count for class unloading.
-    _previous_version_count--;
     return;
   }
 
@@ -3565,12 +3594,12 @@
   }
 
   // Add previous version if any methods are still running.
-  log_trace(redefine, class, iklass, add)("scratch class added; one of its methods is on_stack");
+  // Set has_previous_version flag for processing during class unloading.
+  _has_previous_versions = true;
+  log_trace(redefine, class, iklass, add) ("scratch class added; one of its methods is on_stack.");
   assert(scratch_class->previous_versions() == NULL, "shouldn't have a previous version");
   scratch_class->link_previous_versions(previous_versions());
   link_previous_versions(scratch_class());
-  // Update count for class unloading.
-  _previous_version_count++;
 } // end add_previous_version()
 
 #endif // INCLUDE_JVMTI
--- a/hotspot/src/share/vm/oops/instanceKlass.hpp	Thu Sep 08 23:38:56 2016 -0700
+++ b/hotspot/src/share/vm/oops/instanceKlass.hpp	Fri Sep 09 06:44:31 2016 +0000
@@ -619,8 +619,8 @@
   objArrayOop signers() const;
 
   // host class
-  Klass* host_klass() const              {
-    Klass** hk = (Klass**)adr_host_klass();
+  InstanceKlass* host_klass() const              {
+    InstanceKlass** hk = adr_host_klass();
     if (hk == NULL) {
       return NULL;
     } else {
@@ -628,9 +628,9 @@
       return *hk;
     }
   }
-  void set_host_klass(const Klass* host) {
+  void set_host_klass(const InstanceKlass* host) {
     assert(is_anonymous(), "not anonymous");
-    const Klass** addr = (const Klass**)adr_host_klass();
+    const InstanceKlass** addr = (const InstanceKlass **)adr_host_klass();
     assert(addr != NULL, "no reversed space");
     if (addr != NULL) {
       *addr = host;
@@ -709,6 +709,7 @@
 
   // RedefineClasses() support for previous versions:
   void add_previous_version(instanceKlassHandle ikh, int emcp_method_count);
+  void purge_previous_version_list();
 
   InstanceKlass* previous_versions() const { return _previous_versions; }
 #else
@@ -768,10 +769,15 @@
   }
 
  private:
-  static int  _previous_version_count;
+  static bool  _has_previous_versions;
  public:
-  static void purge_previous_versions(InstanceKlass* ik);
-  static bool has_previous_versions() { return _previous_version_count > 0; }
+  static void purge_previous_versions(InstanceKlass* ik) {
+    if (ik->has_been_redefined()) {
+      ik->purge_previous_version_list();
+    }
+  }
+
+  static bool has_previous_versions_and_reset();
 
   // JVMTI: Support for caching a class file before it is modified by an agent that can do retransformation
   void set_cached_class_file(JvmtiCachedClassFileData *data) {
@@ -792,7 +798,7 @@
 #else // INCLUDE_JVMTI
 
   static void purge_previous_versions(InstanceKlass* ik) { return; };
-  static bool has_previous_versions() { return false; }
+  static bool has_previous_versions_and_reset() { return false; }
 
   void set_cached_class_file(JvmtiCachedClassFileData *data) {
     assert(data == NULL, "unexpected call with JVMTI disabled");
@@ -1057,13 +1063,13 @@
     }
   };
 
-  Klass** adr_host_klass() const {
+  InstanceKlass** adr_host_klass() const {
     if (is_anonymous()) {
-      Klass** adr_impl = adr_implementor();
+      InstanceKlass** adr_impl = (InstanceKlass **)adr_implementor();
       if (adr_impl != NULL) {
         return adr_impl + 1;
       } else {
-        return end_of_nonstatic_oop_maps();
+        return (InstanceKlass **)end_of_nonstatic_oop_maps();
       }
     } else {
       return NULL;
--- a/hotspot/src/share/vm/oops/klass.cpp	Thu Sep 08 23:38:56 2016 -0700
+++ b/hotspot/src/share/vm/oops/klass.cpp	Fri Sep 09 06:44:31 2016 +0000
@@ -431,6 +431,12 @@
     if (clean_alive_klasses && current->is_instance_klass()) {
       InstanceKlass* ik = InstanceKlass::cast(current);
       ik->clean_weak_instanceklass_links(is_alive);
+
+      // JVMTI RedefineClasses creates previous versions that are not in
+      // the class hierarchy, so process them here.
+      while ((ik = ik->previous_versions()) != NULL) {
+        ik->clean_weak_instanceklass_links(is_alive);
+      }
     }
   }
 }
--- a/hotspot/src/share/vm/opto/graphKit.cpp	Thu Sep 08 23:38:56 2016 -0700
+++ b/hotspot/src/share/vm/opto/graphKit.cpp	Fri Sep 09 06:44:31 2016 +0000
@@ -2172,10 +2172,9 @@
       java_bc() == Bytecodes::_instanceof ||
       java_bc() == Bytecodes::_aastore) {
     ciProfileData* data = method()->method_data()->bci_to_data(bci());
-    bool maybe_null = data == NULL ? true : data->as_BitData()->null_seen();
+    maybe_null = data == NULL ? true : data->as_BitData()->null_seen();
   }
   return record_profile_for_speculation(n, exact_kls, maybe_null);
-  return n;
 }
 
 /**
--- a/hotspot/src/share/vm/opto/library_call.cpp	Thu Sep 08 23:38:56 2016 -0700
+++ b/hotspot/src/share/vm/opto/library_call.cpp	Fri Sep 09 06:44:31 2016 +0000
@@ -2475,6 +2475,28 @@
       // load value
       switch (type) {
       case T_BOOLEAN:
+      {
+        // Normalize the value returned by getBoolean in the following cases
+        if (mismatched ||
+            heap_base_oop == top() ||                            // - heap_base_oop is NULL or
+            (can_access_non_heap && alias_type->field() == NULL) // - heap_base_oop is potentially NULL
+                                                                 //   and the unsafe access is made to large offset
+                                                                 //   (i.e., larger than the maximum offset necessary for any
+                                                                 //   field access)
+            ) {
+          IdealKit ideal = IdealKit(this);
+#define __ ideal.
+          IdealVariable normalized_result(ideal);
+          __ declarations_done();
+          __ set(normalized_result, p);
+          __ if_then(p, BoolTest::ne, ideal.ConI(0));
+          __ set(normalized_result, ideal.ConI(1));
+          ideal.end_if();
+          final_sync(ideal);
+          p = __ value(normalized_result);
+#undef __
+        }
+      }
       case T_CHAR:
       case T_BYTE:
       case T_SHORT:
--- a/hotspot/src/share/vm/opto/runtime.cpp	Thu Sep 08 23:38:56 2016 -0700
+++ b/hotspot/src/share/vm/opto/runtime.cpp	Fri Sep 09 06:44:31 2016 +0000
@@ -1349,17 +1349,23 @@
         force_unwind ? NULL : nm->handler_for_exception_and_pc(exception, pc);
 
       if (handler_address == NULL) {
-        Handle original_exception(thread, exception());
-        handler_address = SharedRuntime::compute_compiled_exc_handler(nm, pc, exception, force_unwind, true);
+        bool recursive_exception = false;
+        handler_address = SharedRuntime::compute_compiled_exc_handler(nm, pc, exception, force_unwind, true, recursive_exception);
         assert (handler_address != NULL, "must have compiled handler");
         // Update the exception cache only when the unwind was not forced
         // and there didn't happen another exception during the computation of the
-        // compiled exception handler.
-        if (!force_unwind && original_exception() == exception()) {
+        // compiled exception handler. Checking for exception oop equality is not
+        // sufficient because some exceptions are pre-allocated and reused.
+        if (!force_unwind && !recursive_exception) {
           nm->add_handler_for_exception_and_pc(exception,pc,handler_address);
         }
       } else {
-        assert(handler_address == SharedRuntime::compute_compiled_exc_handler(nm, pc, exception, force_unwind, true), "Must be the same");
+#ifdef ASSERT
+        bool recursive_exception = false;
+        address computed_address = SharedRuntime::compute_compiled_exc_handler(nm, pc, exception, force_unwind, true, recursive_exception);
+        vmassert(recursive_exception || (handler_address == computed_address), "Handler address inconsistency: " PTR_FORMAT " != " PTR_FORMAT,
+                 p2i(handler_address), p2i(computed_address));
+#endif
       }
     }
 
--- a/hotspot/src/share/vm/prims/jvmtiEnv.cpp	Thu Sep 08 23:38:56 2016 -0700
+++ b/hotspot/src/share/vm/prims/jvmtiEnv.cpp	Fri Sep 09 06:44:31 2016 +0000
@@ -649,18 +649,14 @@
 
 jvmtiError
 JvmtiEnv::SetVerboseFlag(jvmtiVerboseFlag flag, jboolean value) {
+  LogLevelType level = value == 0 ? LogLevel::Off : LogLevel::Info;
   switch (flag) {
   case JVMTI_VERBOSE_OTHER:
     // ignore
     break;
   case JVMTI_VERBOSE_CLASS:
-    if (value == 0) {
-      LogConfiguration::parse_log_arguments("stdout", "class+unload=off", NULL, NULL, NULL);
-      LogConfiguration::parse_log_arguments("stdout", "class+load=off", NULL, NULL, NULL);
-    } else {
-      LogConfiguration::parse_log_arguments("stdout", "class+load=info", NULL, NULL, NULL);
-      LogConfiguration::parse_log_arguments("stdout", "class+unload=info", NULL, NULL, NULL);
-    }
+    LogConfiguration::configure_stdout(level, false, LOG_TAGS(class, unload));
+    LogConfiguration::configure_stdout(level, false, LOG_TAGS(class, load));
     break;
   case JVMTI_VERBOSE_GC:
     if (value == 0) {
--- a/hotspot/src/share/vm/prims/unsafe.cpp	Thu Sep 08 23:38:56 2016 -0700
+++ b/hotspot/src/share/vm/prims/unsafe.cpp	Fri Sep 09 06:44:31 2016 +0000
@@ -150,14 +150,23 @@
   }
 
   template <typename T>
-  T normalize(T x) {
+  T normalize_for_write(T x) {
     return x;
   }
 
-  jboolean normalize(jboolean x) {
+  jboolean normalize_for_write(jboolean x) {
     return x & 1;
   }
 
+  template <typename T>
+  T normalize_for_read(T x) {
+    return x;
+  }
+
+  jboolean normalize_for_read(jboolean x) {
+    return x != 0;
+  }
+
   /**
    * Helper class to wrap memory accesses in JavaThread::doing_unsafe_access()
    */
@@ -196,7 +205,7 @@
 
     T* p = (T*)addr();
 
-    T x = *p;
+    T x = normalize_for_read(*p);
 
     return x;
   }
@@ -207,7 +216,7 @@
 
     T* p = (T*)addr();
 
-    *p = normalize(x);
+    *p = normalize_for_write(x);
   }
 
 
@@ -223,7 +232,7 @@
 
     T x = OrderAccess::load_acquire((volatile T*)p);
 
-    return x;
+    return normalize_for_read(x);
   }
 
   template <typename T>
@@ -232,7 +241,7 @@
 
     T* p = (T*)addr();
 
-    OrderAccess::release_store_fence((volatile T*)p, normalize(x));
+    OrderAccess::release_store_fence((volatile T*)p, normalize_for_write(x));
   }
 
 
@@ -256,7 +265,7 @@
 
     jlong* p = (jlong*)addr();
 
-    Atomic::store(normalize(x),  p);
+    Atomic::store(normalize_for_write(x),  p);
   }
 #endif
 };
@@ -783,6 +792,7 @@
 
 // define a class but do not make it known to the class loader or system dictionary
 // - host_class:  supplies context for linkage, access control, protection domain, and class loader
+//                if host_class is itself anonymous then it is replaced with its host class.
 // - data:  bytes of a class file, a raw memory address (length gives the number of bytes)
 // - cp_patches:  where non-null entries exist, they replace corresponding CP entries in data
 
@@ -791,8 +801,12 @@
 // link to any member of U.  Just after U is loaded, the only way to use it is reflectively,
 // through java.lang.Class methods like Class.newInstance.
 
+// The package of an anonymous class must either match its host's class's package or be in the
+// unnamed package.  If it is in the unnamed package then it will be put in its host class's
+// package.
+//
+
 // Access checks for linkage sites within U continue to follow the same rules as for named classes.
-// The package of an anonymous class is given by the package qualifier on the name under which it was loaded.
 // An anonymous class also has special privileges to access any member of its host class.
 // This is the main reason why this loading operation is unsafe.  The purpose of this is to
 // allow language implementations to simulate "open classes"; a host class in effect gets
@@ -874,9 +888,11 @@
 
   // Primitive types have NULL Klass* fields in their java.lang.Class instances.
   if (host_klass == NULL) {
-    THROW_0(vmSymbols::java_lang_IllegalArgumentException());
+    THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Host class is null");
   }
 
+  assert(host_klass->is_instance_klass(), "Host class must be an instance class");
+
   const char* host_source = host_klass->external_name();
   Handle      host_loader(THREAD, host_klass->class_loader());
   Handle      host_domain(THREAD, host_klass->protection_domain());
@@ -907,7 +923,7 @@
                                                 host_loader,
                                                 host_domain,
                                                 &st,
-                                                host_klass,
+                                                InstanceKlass::cast(host_klass),
                                                 cp_patches,
                                                 CHECK_NULL);
   if (anonk == NULL) {
--- a/hotspot/src/share/vm/runtime/arguments.cpp	Thu Sep 08 23:38:56 2016 -0700
+++ b/hotspot/src/share/vm/runtime/arguments.cpp	Fri Sep 09 06:44:31 2016 +0000
@@ -33,8 +33,9 @@
 #include "gc/shared/referenceProcessor.hpp"
 #include "gc/shared/taskqueue.hpp"
 #include "logging/log.hpp"
+#include "logging/logConfiguration.hpp"
+#include "logging/logStream.hpp"
 #include "logging/logTag.hpp"
-#include "logging/logConfiguration.hpp"
 #include "memory/allocation.inline.hpp"
 #include "memory/universe.inline.hpp"
 #include "oops/oop.inline.hpp"
@@ -4176,7 +4177,10 @@
   if (_gc_log_filename != NULL) {
     // -Xloggc was used to specify a filename
     const char* gc_conf = PrintGCDetails ? "gc*" : "gc";
-    return  LogConfiguration::parse_log_arguments(_gc_log_filename, gc_conf, NULL, NULL, NULL);
+
+    LogTarget(Error, logging) target;
+    LogStreamCHeap errstream(target);
+    return LogConfiguration::parse_log_arguments(_gc_log_filename, gc_conf, NULL, NULL, &errstream);
   } else if (PrintGC || PrintGCDetails) {
     LogConfiguration::configure_stdout(LogLevel::Info, !PrintGCDetails, LOG_TAGS(gc));
   }
--- a/hotspot/src/share/vm/runtime/interfaceSupport.hpp	Thu Sep 08 23:38:56 2016 -0700
+++ b/hotspot/src/share/vm/runtime/interfaceSupport.hpp	Fri Sep 09 06:44:31 2016 +0000
@@ -219,6 +219,9 @@
     trans_from_java(_thread_in_vm);
   }
   ~ThreadInVMfromJava()  {
+    if (_thread->stack_yellow_reserved_zone_disabled()) {
+      _thread->enable_stack_yellow_reserved_zone();
+    }
     trans(_thread_in_vm, _thread_in_Java);
     // Check for pending. async. exceptions or suspends.
     if (_thread->has_special_runtime_exit_condition()) _thread->handle_special_runtime_exit_condition();
@@ -306,6 +309,9 @@
     trans_from_java(_thread_in_vm);
   }
   ~ThreadInVMfromJavaNoAsyncException()  {
+    if (_thread->stack_yellow_reserved_zone_disabled()) {
+      _thread->enable_stack_yellow_reserved_zone();
+    }
     trans(_thread_in_vm, _thread_in_Java);
     // NOTE: We do not check for pending. async. exceptions.
     // If we did and moved the pending async exception over into the
@@ -314,6 +320,7 @@
     // to the _thread_in_vm state. Instead we postpone the handling of
     // the async exception.
 
+
     // Check for pending. suspends only.
     if (_thread->has_special_runtime_exit_condition())
       _thread->handle_special_runtime_exit_condition(false);
--- a/hotspot/src/share/vm/runtime/reflection.cpp	Thu Sep 08 23:38:56 2016 -0700
+++ b/hotspot/src/share/vm/runtime/reflection.cpp	Fri Sep 09 06:44:31 2016 +0000
@@ -412,13 +412,13 @@
   return result;
 }
 
-static bool under_host_klass(const InstanceKlass* ik, const Klass* host_klass) {
+static bool under_host_klass(const InstanceKlass* ik, const InstanceKlass* host_klass) {
   DEBUG_ONLY(int inf_loop_check = 1000 * 1000 * 1000);
   for (;;) {
-    const Klass* hc = (const Klass*)ik->host_klass();
+    const InstanceKlass* hc = ik->host_klass();
     if (hc == NULL)        return false;
     if (hc == host_klass)  return true;
-    ik = InstanceKlass::cast(hc);
+    ik = hc;
 
     // There's no way to make a host class loop short of patching memory.
     // Therefore there cannot be a loop here unless there's another bug.
@@ -436,8 +436,8 @@
 
   // If either is on the other's host_klass chain, access is OK,
   // because one is inside the other.
-  if (under_host_klass(accessor_ik, accessee) ||
-    under_host_klass(accessee_ik, accessor))
+  if (under_host_klass(accessor_ik, accessee_ik) ||
+    under_host_klass(accessee_ik, accessor_ik))
     return true;
 
   if ((RelaxAccessControlCheck &&
--- a/hotspot/src/share/vm/runtime/sharedRuntime.cpp	Thu Sep 08 23:38:56 2016 -0700
+++ b/hotspot/src/share/vm/runtime/sharedRuntime.cpp	Fri Sep 09 06:44:31 2016 +0000
@@ -621,7 +621,7 @@
 // ret_pc points into caller; we are returning caller's exception handler
 // for given exception
 address SharedRuntime::compute_compiled_exc_handler(CompiledMethod* cm, address ret_pc, Handle& exception,
-                                                    bool force_unwind, bool top_frame_only) {
+                                                    bool force_unwind, bool top_frame_only, bool& recursive_exception_occurred) {
   assert(cm != NULL, "must exist");
   ResourceMark rm;
 
@@ -677,6 +677,7 @@
         // BCI of the exception handler which caused the exception to be
         // thrown (bugs 4307310 and 4546590). Set "exception" reference
         // argument to ensure that the correct exception is thrown (4870175).
+        recursive_exception_occurred = true;
         exception = Handle(THREAD, PENDING_EXCEPTION);
         CLEAR_PENDING_EXCEPTION;
         if (handler_bci >= 0) {
--- a/hotspot/src/share/vm/runtime/sharedRuntime.hpp	Thu Sep 08 23:38:56 2016 -0700
+++ b/hotspot/src/share/vm/runtime/sharedRuntime.hpp	Fri Sep 09 06:44:31 2016 +0000
@@ -189,7 +189,7 @@
 
   // exception handling and implicit exceptions
   static address compute_compiled_exc_handler(CompiledMethod* nm, address ret_pc, Handle& exception,
-                                              bool force_unwind, bool top_frame_only);
+                                              bool force_unwind, bool top_frame_only, bool& recursive_exception_occurred);
   enum ImplicitExceptionKind {
     IMPLICIT_NULL,
     IMPLICIT_DIVIDE_BY_ZERO,
--- a/hotspot/src/share/vm/services/classLoadingService.cpp	Thu Sep 08 23:38:56 2016 -0700
+++ b/hotspot/src/share/vm/services/classLoadingService.cpp	Fri Sep 09 06:44:31 2016 +0000
@@ -183,11 +183,8 @@
 bool ClassLoadingService::set_verbose(bool verbose) {
   MutexLocker m(Management_lock);
   // verbose will be set to the previous value
-  if (verbose) {
-    LogConfiguration::parse_log_arguments("stdout", "class+load=info", NULL, NULL, NULL);
-  } else {
-    LogConfiguration::parse_log_arguments("stdout", "class+load=off", NULL, NULL, NULL);
-  }
+  LogLevelType level = verbose ? LogLevel::Info : LogLevel::Off;
+  LogConfiguration::configure_stdout(level, false, LOG_TAGS(class, load));
   reset_trace_class_unloading();
   return verbose;
 }
@@ -196,11 +193,8 @@
 void ClassLoadingService::reset_trace_class_unloading() {
   assert(Management_lock->owned_by_self(), "Must own the Management_lock");
   bool value = MemoryService::get_verbose() || ClassLoadingService::get_verbose();
-  if (value) {
-    LogConfiguration::parse_log_arguments("stdout", "class+unload=info", NULL, NULL, NULL);
-  } else {
-    LogConfiguration::parse_log_arguments("stdout", "class+unload=off", NULL, NULL, NULL);
-  }
+  LogLevelType level = value ? LogLevel::Info : LogLevel::Off;
+  LogConfiguration::configure_stdout(level, false, LOG_TAGS(class, unload));
 }
 
 GrowableArray<KlassHandle>* LoadedClassesEnumerator::_loaded_classes = NULL;
--- a/hotspot/test/compiler/codecache/OverflowCodeCacheTest.java	Thu Sep 08 23:38:56 2016 -0700
+++ b/hotspot/test/compiler/codecache/OverflowCodeCacheTest.java	Fri Sep 09 06:44:31 2016 +0000
@@ -75,6 +75,7 @@
         System.out.printf("type %s%n", type);
         System.out.println("allocating till possible...");
         ArrayList<Long> blobs = new ArrayList<>();
+        int compilationActivityMode = -1;
         try {
             long addr;
             int size = (int) (getHeapSize() >> 7);
@@ -88,13 +89,16 @@
                             type + " doesn't allow using " + actualType + " when overflow");
                 }
             }
-            Asserts.assertNotEquals(WHITE_BOX.getCompilationActivityMode(), 1 /* run_compilation*/,
-                    "Compilation must be disabled when CodeCache(CodeHeap) overflows");
+            /* now, remember compilationActivityMode to check it later, after freeing, since we
+               possibly have no free cache for futher work */
+            compilationActivityMode = WHITE_BOX.getCompilationActivityMode();
         } finally {
             for (Long blob : blobs) {
                 WHITE_BOX.freeCodeBlob(blob);
             }
         }
+        Asserts.assertNotEquals(compilationActivityMode, 1 /* run_compilation*/,
+                "Compilation must be disabled when CodeCache(CodeHeap) overflows");
     }
 
     private long getHeapSize() {
--- a/hotspot/test/compiler/jsr292/CallSiteDepContextTest.java	Thu Sep 08 23:38:56 2016 -0700
+++ b/hotspot/test/compiler/jsr292/CallSiteDepContextTest.java	Fri Sep 09 06:44:31 2016 +0000
@@ -62,7 +62,7 @@
 public class CallSiteDepContextTest {
     static final Unsafe               UNSAFE = Unsafe.getUnsafe();
     static final MethodHandles.Lookup LOOKUP = MethodHandleHelper.IMPL_LOOKUP;
-    static final String           CLASS_NAME = "java/lang/invoke/Test";
+    static final String           CLASS_NAME = "compiler/jsr292/Test";
     static final String          METHOD_NAME = "m";
     static final MethodType TYPE = MethodType.methodType(int.class);
 
@@ -129,8 +129,8 @@
     }
 
     public static void testSharedCallSite() throws Throwable {
-        Class<?> cls1 = UNSAFE.defineAnonymousClass(Object.class, getClassFile("CS_1"), null);
-        Class<?> cls2 = UNSAFE.defineAnonymousClass(Object.class, getClassFile("CS_2"), null);
+        Class<?> cls1 = UNSAFE.defineAnonymousClass(CallSiteDepContextTest.class, getClassFile("CS_1"), null);
+        Class<?> cls2 = UNSAFE.defineAnonymousClass(CallSiteDepContextTest.class, getClassFile("CS_2"), null);
 
         MethodHandle[] mhs = new MethodHandle[] {
                 LOOKUP.findStatic(cls1, METHOD_NAME, TYPE),
@@ -151,7 +151,7 @@
         execute(1, mh);
 
         // mcs.context == cls1
-        Class<?> cls1 = UNSAFE.defineAnonymousClass(Object.class, getClassFile("NonBound_1"), null);
+        Class<?> cls1 = UNSAFE.defineAnonymousClass(CallSiteDepContextTest.class, getClassFile("NonBound_1"), null);
         MethodHandle mh1 = LOOKUP.findStatic(cls1, METHOD_NAME, TYPE);
 
         execute(1, mh1);
@@ -170,8 +170,8 @@
         mcs = new MutableCallSite(LOOKUP.findStatic(T.class, "f1", TYPE));
 
         Class<?>[] cls = new Class[] {
-                UNSAFE.defineAnonymousClass(Object.class, getClassFile("GC_1" + id), null),
-                UNSAFE.defineAnonymousClass(Object.class, getClassFile("GC_2" + id), null),
+                UNSAFE.defineAnonymousClass(CallSiteDepContextTest.class, getClassFile("GC_1" + id), null),
+                UNSAFE.defineAnonymousClass(CallSiteDepContextTest.class, getClassFile("GC_2" + id), null),
         };
 
         MethodHandle[] mhs = new MethodHandle[] {
@@ -185,7 +185,7 @@
         execute(1, mhs);
 
         ref = new PhantomReference<>(cls[0], rq);
-        cls[0] = UNSAFE.defineAnonymousClass(Object.class, getClassFile("GC_3" + id), null);
+        cls[0] = UNSAFE.defineAnonymousClass(CallSiteDepContextTest.class, getClassFile("GC_3" + id), null);
         mhs[0] = LOOKUP.findStatic(cls[0], METHOD_NAME, TYPE);
 
         do {
--- a/hotspot/test/compiler/jvmci/compilerToVM/ExecuteInstalledCodeTest.java	Thu Sep 08 23:38:56 2016 -0700
+++ b/hotspot/test/compiler/jvmci/compilerToVM/ExecuteInstalledCodeTest.java	Fri Sep 09 06:44:31 2016 +0000
@@ -19,7 +19,6 @@
  * @requires (vm.simpleArch == "x64" | vm.simpleArch == "sparcv9" | vm.simpleArch == "aarch64")
  * @library /test/lib /
  * @library ../common/patches
- * @ignore 8139383
  * @modules java.base/jdk.internal.misc
  * @modules java.base/jdk.internal.org.objectweb.asm
  *          java.base/jdk.internal.org.objectweb.asm.tree
--- a/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaType.java	Thu Sep 08 23:38:56 2016 -0700
+++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaType.java	Fri Sep 09 06:44:31 2016 +0000
@@ -25,7 +25,6 @@
  * @test
  * @requires (vm.simpleArch == "x64" | vm.simpleArch == "sparcv9" | vm.simpleArch == "aarch64")
  * @library ../../../../../
- * @ignore 8161550
  * @modules java.base/jdk.internal.reflect
  *          jdk.vm.ci/jdk.vm.ci.meta
  *          jdk.vm.ci/jdk.vm.ci.runtime
@@ -74,11 +73,29 @@
 /**
  * Tests for {@link ResolvedJavaType}.
  */
+@SuppressWarnings("unchecked")
 public class TestResolvedJavaType extends TypeUniverse {
+    private static final Class<? extends Annotation> SIGNATURE_POLYMORPHIC_CLASS = findPolymorphicSignatureClass();
 
     public TestResolvedJavaType() {
     }
 
+    private static Class<? extends Annotation> findPolymorphicSignatureClass() {
+        Class<? extends Annotation> signaturePolyAnnotation = null;
+        try {
+            for (Class<?> clazz : TestResolvedJavaType.class.getClassLoader().loadClass("java.lang.invoke.MethodHandle").getDeclaredClasses()) {
+                if (clazz.getName().endsWith("PolymorphicSignature") && Annotation.class.isAssignableFrom(clazz)) {
+                    signaturePolyAnnotation = (Class<? extends Annotation>) clazz;
+                    break;
+                }
+            }
+        } catch (Throwable e) {
+            throw new AssertionError("Could not find annotation PolymorphicSignature in java.lang.invoke.MethodHandle", e);
+        }
+        assertNotNull(signaturePolyAnnotation);
+        return signaturePolyAnnotation;
+    }
+
     @Test
     public void findInstanceFieldWithOffsetTest() {
         for (Class<?> c : classes) {
@@ -577,8 +594,14 @@
                     for (Method decl : decls) {
                         ResolvedJavaMethod m = metaAccess.lookupJavaMethod(decl);
                         if (m.isPublic()) {
-                            ResolvedJavaMethod i = metaAccess.lookupJavaMethod(impl);
-                            assertEquals(m.toString(), i, type.resolveMethod(m, context));
+                            ResolvedJavaMethod resolvedmethod = type.resolveMethod(m, context);
+                            if (isSignaturePolymorphic(m)) {
+                                // Signature polymorphic methods must not be resolved
+                                assertNull(resolvedmethod);
+                            } else {
+                                ResolvedJavaMethod i = metaAccess.lookupJavaMethod(impl);
+                                assertEquals(m.toString(), i, resolvedmethod);
+                            }
                         }
                     }
                 }
@@ -606,8 +629,14 @@
                     for (Method decl : decls) {
                         ResolvedJavaMethod m = metaAccess.lookupJavaMethod(decl);
                         if (m.isPublic()) {
-                            ResolvedJavaMethod i = metaAccess.lookupJavaMethod(impl);
-                            assertEquals(i, type.resolveConcreteMethod(m, context));
+                            ResolvedJavaMethod resolvedMethod = type.resolveConcreteMethod(m, context);
+                            if (isSignaturePolymorphic(m)) {
+                                // Signature polymorphic methods must not be resolved
+                                assertNull(String.format("Got: %s", resolvedMethod), resolvedMethod);
+                            } else {
+                                ResolvedJavaMethod i = metaAccess.lookupJavaMethod(impl);
+                                assertEquals(i, resolvedMethod);
+                            }
                         }
                     }
                 }
@@ -929,4 +958,8 @@
             }
         }
     }
+
+    private static boolean isSignaturePolymorphic(ResolvedJavaMethod method) {
+        return method.getAnnotation(SIGNATURE_POLYMORPHIC_CLASS) != null;
+    }
 }
--- a/hotspot/test/compiler/loopopts/UseCountedLoopSafepoints.java	Thu Sep 08 23:38:56 2016 -0700
+++ b/hotspot/test/compiler/loopopts/UseCountedLoopSafepoints.java	Fri Sep 09 06:44:31 2016 +0000
@@ -22,51 +22,32 @@
  *
  */
 
-/**
- * @test
- * @bug 6869327
- * @summary Test that C2 flag UseCountedLoopSafepoints ensures a safepoint is kept in a CountedLoop
- * @library /test/lib
- * @modules java.base/jdk.internal.misc
- * @ignore 8146096
- * @run driver compiler.loopopts.UseCountedLoopSafepoints
- */
-
 package compiler.loopopts;
 
-import jdk.test.lib.process.OutputAnalyzer;
-import jdk.test.lib.process.ProcessTools;
-
-import java.util.concurrent.atomic.AtomicLong;
+import java.lang.reflect.Method;
+import sun.hotspot.WhiteBox;
+import jdk.test.lib.Asserts;
+import compiler.whitebox.CompilerWhiteBoxTest;
 
 public class UseCountedLoopSafepoints {
-    private static final AtomicLong _num = new AtomicLong(0);
+    private static final WhiteBox WB = WhiteBox.getWhiteBox();
+    private static final String METHOD_NAME = "testMethod";
 
-    // Uses the fact that an EnableBiasedLocking vmop will be started
-    // after 500ms, while we are still in the loop. If there is a
-    // safepoint in the counted loop, then we will reach safepoint
-    // very quickly. Otherwise SafepointTimeout will be hit.
+    private long accum = 0;
+
     public static void main (String args[]) throws Exception {
-        if (args.length == 1) {
-            final int loops = Integer.parseInt(args[0]);
-            for (int i = 0; i < loops; i++) {
-                _num.addAndGet(1);
-            }
-        } else {
-            ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
-                    "-XX:+IgnoreUnrecognizedVMOptions",
-                    "-XX:-TieredCompilation",
-                    "-XX:+UseBiasedLocking",
-                    "-XX:BiasedLockingStartupDelay=500",
-                    "-XX:+SafepointTimeout",
-                    "-XX:SafepointTimeoutDelay=2000",
-                    "-XX:+UseCountedLoopSafepoints",
-                    UseCountedLoopSafepoints.class.getName(),
-                    "2000000000"
-                    );
-            OutputAnalyzer output = new OutputAnalyzer(pb.start());
-            output.shouldNotContain("Timeout detected");
-            output.shouldHaveExitValue(0);
+        new UseCountedLoopSafepoints().testMethod();
+        Method m = UseCountedLoopSafepoints.class.getDeclaredMethod(METHOD_NAME);
+        String directive = "[{ match: \"" + UseCountedLoopSafepoints.class.getName().replace('.', '/')
+                + "." + METHOD_NAME + "\", " + "BackgroundCompilation: false }]";
+        Asserts.assertTrue(WB.addCompilerDirective(directive) == 1, "Can't add compiler directive");
+        Asserts.assertTrue(WB.enqueueMethodForCompilation(m,
+                CompilerWhiteBoxTest.COMP_LEVEL_FULL_OPTIMIZATION), "Can't enqueue method");
+    }
+
+    private void testMethod() {
+        for (int i = 0; i < 100; i++) {
+            accum += accum << 5 + accum >> 4 - accum >>> 5;
         }
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/loopopts/UseCountedLoopSafepointsTest.java	Fri Sep 09 06:44:31 2016 +0000
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/**
+ * @test
+ * @bug 6869327
+ * @summary Test that C2 flag UseCountedLoopSafepoints ensures a safepoint is kept in a CountedLoop
+ * @library /test/lib /
+ * @requires vm.compMode != "Xint" & vm.flavor == "server" & (vm.opt.TieredStopAtLevel == null | vm.opt.TieredStopAtLevel == 4)
+ * @modules java.base/jdk.internal.misc
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ *                                sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run driver compiler.loopopts.UseCountedLoopSafepointsTest
+ */
+
+package compiler.loopopts;
+
+import jdk.test.lib.process.ProcessTools;
+import jdk.test.lib.process.OutputAnalyzer;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import jdk.test.lib.Asserts;
+
+/* Idea of this test is to check if ideal graph has CountedLoopEnd->SafePoint edge in case
+   of UseCountedLoopSafepoint enabled and has no such edge in case it's disabled. Restricting
+   compilation to testMethod only will leave only one counted loop (the one in testedMethod) */
+public class UseCountedLoopSafepointsTest {
+
+    public static void main (String args[]) {
+        check(true); // check ideal graph with UseCountedLoopSafepoint enabled
+        check(false); // ... and disabled
+    }
+
+    private static void check(boolean enabled) {
+        OutputAnalyzer oa;
+        try {
+            oa = ProcessTools.executeTestJvm("-XX:+UnlockDiagnosticVMOptions", "-Xbootclasspath/a:.",
+                    "-XX:" + (enabled ? "+" : "-") + "UseCountedLoopSafepoints", "-XX:+WhiteBoxAPI",
+                    "-XX:-Inline", "-Xbatch", "-XX:+PrintIdeal", "-XX:LoopUnrollLimit=0",
+                    "-XX:CompileOnly=" + UseCountedLoopSafepoints.class.getName() + "::testMethod",
+                    UseCountedLoopSafepoints.class.getName());
+        } catch (Exception e) {
+            throw new Error("Exception launching child for case enabled=" + enabled + " : " + e, e);
+        }
+        oa.shouldHaveExitValue(0);
+        // parse output in seach of SafePoint and CountedLoopEnd nodes
+        List<Node> safePoints = new ArrayList<>();
+        List<Node> loopEnds = new ArrayList<>();
+        for (String line : oa.getOutput().split("\\n")) {
+            int separatorIndex = line.indexOf("\t===");
+            if (separatorIndex > -1) {
+                String header = line.substring(0, separatorIndex);
+                if (header.endsWith("\tSafePoint")) {
+                    safePoints.add(new Node("SafePoint", line));
+                } else if (header.endsWith("\tCountedLoopEnd")) {
+                    loopEnds.add(new Node("CountedLoopEnd", line));
+                }
+            }
+        }
+        // now, find CountedLoopEnd -> SafePoint edge
+        boolean found = false;
+        for (Node loopEnd : loopEnds) {
+            found |= loopEnd.to.stream()
+                                 .filter(id -> nodeListHasElementWithId(safePoints, id))
+                                 .findAny()
+                                 .isPresent();
+        }
+        Asserts.assertEQ(enabled, found, "Safepoint " + (found ? "" : "not ") + "found");
+    }
+
+    private static boolean nodeListHasElementWithId(List<Node> list, int id) {
+        return list.stream()
+                   .filter(node -> node.id == id)
+                   .findAny()
+                   .isPresent();
+    }
+
+    private static class Node {
+        public final int id;
+        public final List<Integer> from;
+        public final List<Integer> to;
+
+        public Node(String name, String str) {
+            List<Integer> tmpFrom = new ArrayList<>();
+            List<Integer> tmpTo = new ArrayList<>();
+            // parse string like: " $id    $name       ===  $to1 $to2 ...   [[ $from1 $from2 ... ]] $anything"
+            // example:  318    SafePoint       ===  317  1  304  1  1  10  308  [[ 97  74 ]]  ...
+            id = Integer.parseInt(str.substring(1, str.indexOf(name)).trim());
+            Arrays.stream(str.substring(str.indexOf("===") + 4, str.indexOf("[[")).trim().split("\\s+"))
+                  .map(Integer::parseInt)
+                  .forEach(tmpTo::add);
+            Arrays.stream(str.substring(str.indexOf("[[") + 3, str.indexOf("]]")).trim().split("\\s+"))
+                  .map(Integer::parseInt)
+                  .forEach(tmpFrom::add);
+            this.from = Collections.unmodifiableList(tmpFrom);
+            this.to = Collections.unmodifiableList(tmpTo);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/unsafe/UnsafeOffHeapBooleanTest.java	Fri Sep 09 06:44:31 2016 +0000
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8161720
+ * @modules java.base/jdk.internal.misc
+ * @run main/othervm -Xint UnsafeOffHeapBooleanTest 1
+ * @run main/othervm -XX:+TieredCompilation -XX:TieredStopAtLevel=3 -Xbatch  UnsafeOffHeapBooleanTest 20000
+ * @run main/othervm -XX:-TieredCompilation -Xbatch UnsafeOffHeapBooleanTest 20000
+ */
+
+
+import java.lang.reflect.Field;
+import jdk.internal.misc.Unsafe;
+
+public class UnsafeOffHeapBooleanTest {
+    static boolean bool0 = false, bool1 = false, result = false;
+    static Unsafe UNSAFE = Unsafe.getUnsafe();
+    static long offHeapMemory;
+
+    public static void test() {
+        // Write two bytes to the off-heap memory location, both
+        // bytes correspond to the boolean value 'true'.
+        UNSAFE.putShort(null, offHeapMemory, (short)0x0204);
+
+        // Read two bytes from the storage allocated above (as booleans).
+        bool0 = UNSAFE.getBoolean(null, offHeapMemory + 0);
+        bool1 = UNSAFE.getBoolean(null, offHeapMemory + 1);
+        result = bool0 & bool1;
+    }
+
+    public static void main(String args[]) {
+        System.out.println("### Test started");
+
+        if (args.length != 1) {
+            throw new RuntimeException("### Test failure: test called with incorrect number of arguments");
+        }
+
+        // Allocate two bytes of storage.
+        offHeapMemory = UNSAFE.allocateMemory(2);
+
+        try {
+            for (int i = 0; i < Integer.parseInt(args[0]); i++) {
+                test();
+            }
+
+            // Check if the two 'true' boolean values were normalized
+            // (i.e., reduced from the range 1...255 to 1).
+            if (!bool0 || !bool1 || !result) {
+                System.out.println("Some of the results below are wrong");
+                System.out.println("bool0 is: " + bool0);
+                System.out.println("bool1 is: " + bool1);
+                System.out.println("bool0 & bool1 is: " + result);
+                System.out.println("===================================");
+                throw new RuntimeException("### Test failed");
+            } else {
+                System.out.println("Test generated correct results");
+                System.out.println("bool0 is: " + bool0);
+                System.out.println("bool1 is: " + bool1);
+                System.out.println("bool0 & bool1 is: " + result);
+                System.out.println("===================================");
+            }
+        } catch (NumberFormatException e) {
+            throw new RuntimeException("### Test failure: test called with incorrectly formatted parameter");
+        }
+
+        UNSAFE.freeMemory(offHeapMemory);
+
+        System.out.println("### Test passed");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/unsafe/UnsafeOnHeapBooleanTest.java	Fri Sep 09 06:44:31 2016 +0000
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8161720
+ * @modules java.base/jdk.internal.misc
+ * @run main/othervm -Xint UnsafeOnHeapBooleanTest 1
+ * @run main/othervm -XX:-UseOnStackReplacement -XX:+TieredCompilation -XX:TieredStopAtLevel=3 -Xbatch UnsafeOnHeapBooleanTest 20000
+ * @run main/othervm -XX:-UseOnStackReplacement -XX:-TieredCompilation -Xbatch UnsafeOnHeapBooleanTest 20000
+ */
+
+import java.lang.reflect.Field;
+import jdk.internal.misc.Unsafe;
+
+public class UnsafeOnHeapBooleanTest {
+    static short static_v;
+    static boolean bool0 = false, bool1 = false, result = false;
+    static Unsafe UNSAFE = Unsafe.getUnsafe();
+
+    public static void test() {
+        try {
+            // Write two bytes into the static field
+            // UnsafeOnHeapBooleanTest.static_v write two values. Both
+            // bytes correspond to the boolean value 'true'.
+            Field staticVField = UnsafeOnHeapBooleanTest.class.getDeclaredField("static_v");
+            Object base = UNSAFE.staticFieldBase(staticVField);
+            long offset = UNSAFE.staticFieldOffset(staticVField);
+            UNSAFE.putShort(base, offset, (short)0x0204);
+
+            // Read two bytes from the static field
+            // UnsafeOnHeapBooleanTest.static_v (as booleans).
+            bool0 = UNSAFE.getBoolean(base, offset + 0);
+            bool1 = UNSAFE.getBoolean(base, offset + 1);
+            result = bool0 & bool1;
+        } catch (NoSuchFieldException e) {
+            throw new RuntimeException("### Test failure: static field UnsafeOnHeapBooleanTest.static_v was not found");
+        }
+    }
+
+    public static void main(String args[]) {
+        System.out.println("### Test started");
+
+        if (args.length != 1) {
+            throw new RuntimeException("### Test failure: test called with incorrect number of arguments");
+        }
+
+        try {
+            for (int i = 0; i < Integer.parseInt(args[0]); i++) {
+                test();
+            }
+
+            // Check if the two 'true' boolean values were normalized
+            // (i.e., reduced from the range 1...255 to 1).
+            if (!bool0 || !bool1 || !result) {
+                System.out.println("Some of the results below are wrong");
+                System.out.println("bool0 is: " + bool0);
+                System.out.println("bool1 is: " + bool1);
+                System.out.println("bool0 & bool1 is: " + result);
+                System.out.println("===================================");
+                throw new RuntimeException("### Test failed");
+            } else {
+                System.out.println("Test generated correct results");
+                System.out.println("bool0 is: " + bool0);
+                System.out.println("bool1 is: " + bool1);
+                System.out.println("bool0 & bool1 is: " + result);
+                System.out.println("===================================");
+            }
+        } catch (NumberFormatException e) {
+            throw new RuntimeException("### Test failure: test called with incorrectly formatted parameter");
+        }
+
+        System.out.println("### Test passed");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/unsafe/UnsafeSmallOffsetBooleanAccessTest.java	Fri Sep 09 06:44:31 2016 +0000
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8161720
+ * @modules java.base/jdk.internal.misc
+ * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -Xbatch -XX:-TieredCompilation UnsafeSmallOffsetBooleanAccessTest
+ * @run main/othervm -Xbatch UnsafeSmallOffsetBooleanAccessTest
+ */
+
+import java.util.Random;
+import jdk.internal.misc.Unsafe;
+
+public class UnsafeSmallOffsetBooleanAccessTest {
+    static final Unsafe UNSAFE = Unsafe.getUnsafe();
+    static final long F_OFFSET;
+    static final Random random = new Random();
+
+    static {
+        try {
+            F_OFFSET = UNSAFE.objectFieldOffset(T.class.getDeclaredField("f"));
+            System.out.println("The offset is: " + F_OFFSET);
+        } catch (Exception e) {
+            throw new Error(e);
+        }
+    }
+
+    static class T {
+        boolean f;
+    }
+
+    // Always return false in a way that is not obvious to the compiler.
+    public static boolean myRandom() {
+        if (random.nextInt(101) > 134) {
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    public static boolean test(T t) {
+        boolean result = false;
+        for (int i = 0; i < 20000; i++) {
+            boolean random = myRandom();
+            // If myRandom() returns false, access t.f.
+            //
+            // If myRandom() returns true, access virtual address
+            // F_OFFSET. That address is most likely not mapped,
+            // therefore the access will most likely cause a
+            // crash. We're not concerned about that, though, because
+            // myRandom() always returns false. However, the C2
+            // compiler avoids normalization of the value returned by
+            // getBoolean in this case.
+            result = UNSAFE.getBoolean(myRandom() ? null : t, F_OFFSET);
+        }
+        return result;
+    }
+
+    public static void main(String[] args) {
+        T t = new T();
+        UNSAFE.putBoolean(t, F_OFFSET, true);
+        System.out.println("The result for t is: " + test(t));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/gc/TestNumWorkerOutput.java	Fri Sep 09 06:44:31 2016 +0000
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test TestNumWorkerOutput
+ * @bug 8165292
+ * @summary Check that when PrintGCDetails is enabled, gc,task output is printed only once per collection.
+ * @key gc
+ * @requires vm.gc=="null"
+ * @modules java.base/jdk.internal.misc
+ * @library /test/lib
+ * @build sun.hotspot.WhiteBox
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -XX:+UseConcMarkSweepGC TestNumWorkerOutput UseConcMarkSweepGC
+ * @run main/othervm -XX:+UseG1GC TestNumWorkerOutput UseG1GC
+ */
+
+import sun.hotspot.WhiteBox;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import jdk.test.lib.Platform;
+import jdk.test.lib.process.OutputAnalyzer;
+import jdk.test.lib.process.ProcessTools;
+
+import static jdk.test.lib.Asserts.*;
+
+public class TestNumWorkerOutput {
+
+    public static void checkPatternOnce(String pattern, String what) throws Exception {
+        Pattern r = Pattern.compile(pattern);
+        Matcher m = r.matcher(what);
+
+        if (!m.find()) {
+            throw new RuntimeException("Could not find pattern " + pattern + " in output");
+        }
+        if (m.find()) {
+            throw new RuntimeException("Could find pattern " + pattern + " in output more than once");
+        }
+    }
+
+    public static void runTest(String gcArg) throws Exception {
+        final String[] arguments = {
+            "-Xbootclasspath/a:.",
+            "-XX:+UnlockExperimentalVMOptions",
+            "-XX:+UnlockDiagnosticVMOptions",
+            "-XX:+WhiteBoxAPI",
+            "-XX:+" + gcArg,
+            "-Xmx10M",
+            "-XX:+PrintGCDetails",
+            GCTest.class.getName()
+            };
+
+        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(arguments);
+        OutputAnalyzer output = new OutputAnalyzer(pb.start());
+
+        output.shouldHaveExitValue(0);
+
+        System.out.println(output.getStdout());
+
+        String stdout = output.getStdout();
+
+        checkPatternOnce(".*[info.*].*[gc,task.*].*GC\\(0\\) .*Using \\d+ workers of \\d+ for evacuation.*", stdout);
+    }
+
+    public static void main(String[] args) throws Exception {
+        runTest(args[0]);
+    }
+
+    static class GCTest {
+        private static final WhiteBox WB = WhiteBox.getWhiteBox();
+
+        public static Object holder;
+
+        public static void main(String [] args) {
+            holder = new byte[100];
+            WB.youngGC();
+            System.out.println(holder);
+        }
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/RedefineTests/RedefinePreviousVersions.java	Fri Sep 09 06:44:31 2016 +0000
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8165246
+ * @summary Test has_previous_versions flag and processing during class unloading.
+ * @library /test/lib
+ * @modules java.base/jdk.internal.misc
+ * @modules java.compiler
+ *          java.instrument
+ *          jdk.jartool/sun.tools.jar
+ * @run main RedefineClassHelper
+ * @run main/othervm RedefinePreviousVersions test
+ */
+
+import jdk.test.lib.process.ProcessTools;
+import jdk.test.lib.process.OutputAnalyzer;
+
+public class RedefinePreviousVersions {
+
+    public static String newB =
+                "class RedefinePreviousVersions$B {" +
+                "}";
+
+    static class B { }
+
+    public static String newRunning =
+        "class RedefinePreviousVersions$Running {" +
+        "    public static volatile boolean stop = true;" +
+        "    static void localSleep() { }" +
+        "    public static void infinite() { }" +
+        "}";
+
+    static class Running {
+        public static volatile boolean stop = false;
+        static void localSleep() {
+          try{
+            Thread.currentThread().sleep(10);//sleep for 10 ms
+          } catch(InterruptedException ie) {
+          }
+        }
+
+        public static void infinite() {
+            while (!stop) { localSleep(); }
+        }
+    }
+
+    public static void main(String[] args) throws Exception {
+
+        if (args.length > 0) {
+
+            String jarFile = System.getProperty("test.src") + "/testcase.jar";
+
+            // java -javaagent:redefineagent.jar -Xlog:stuff RedefinePreviousVersions
+            ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( "-javaagent:redefineagent.jar",
+               "-Xlog:redefine+class+iklass+add=trace,redefine+class+iklass+purge=trace",
+               "RedefinePreviousVersions");
+            new OutputAnalyzer(pb.start())
+              .shouldContain("Class unloading: has_previous_versions = false")
+              .shouldContain("Class unloading: has_previous_versions = true")
+              .shouldHaveExitValue(0);
+            return;
+        }
+
+        // Redefine a class and create some garbage
+        // Since there are no methods running, the previous version is never added to the
+        // previous_version_list and the flag _has_previous_versions should stay false
+        RedefineClassHelper.redefineClass(B.class, newB);
+
+        for (int i = 0; i < 10 ; i++) {
+            String s = new String("some garbage");
+            System.gc();
+        }
+
+        // Start a class that has a method running
+        new Thread() {
+            public void run() {
+                Running.infinite();
+            }
+        }.start();
+
+        // Since a method of newRunning is running, this class should be added to the previous_version_list
+        // of Running, and _has_previous_versions should return true at class unloading.
+        RedefineClassHelper.redefineClass(Running.class, newRunning);
+
+        for (int i = 0; i < 10 ; i++) {
+            String s = new String("some garbage");
+            System.gc();
+        }
+
+        // purge should clean everything up, except Xcomp it might not.
+        Running.stop = true;
+
+        for (int i = 0; i < 10 ; i++) {
+            String s = new String("some garbage");
+            System.gc();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/defineAnonClass/DefineAnon.java	Fri Sep 09 06:44:31 2016 +0000
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test DefineAnon
+ * @bug 8058575
+ * @library /testlibrary
+ * @modules java.base/jdk.internal.org.objectweb.asm
+ *          java.management
+ * @compile -XDignore.symbol.file=true DefineAnon.java
+ * @run main/othervm p1.DefineAnon
+ */
+
+package p1;
+
+import jdk.internal.org.objectweb.asm.ClassWriter;
+import jdk.internal.org.objectweb.asm.MethodVisitor;
+import jdk.internal.org.objectweb.asm.Opcodes;
+import sun.misc.Unsafe;
+
+
+class T {
+    static           protected void test0() { System.out.println("test0 (public)"); }
+    static           protected void test1() { System.out.println("test1 (protected)"); }
+    static /*package-private*/ void test2() { System.out.println("test2 (package)"); }
+    static             private void test3() { System.out.println("test3 (private)"); }
+}
+
+public class DefineAnon {
+
+    private static Unsafe getUnsafe() {
+        try {
+            java.lang.reflect.Field singleoneInstanceField = Unsafe.class.getDeclaredField("theUnsafe");
+            singleoneInstanceField.setAccessible(true);
+            return (Unsafe) singleoneInstanceField.get(null);
+        } catch (Throwable ex) {
+            throw new RuntimeException("Was unable to get Unsafe instance.");
+        }
+    }
+
+    static Unsafe UNSAFE = DefineAnon.getUnsafe();
+
+    static Class<?> getAnonClass(Class<?> hostClass, final String className) {
+        final String superName = "java/lang/Object";
+        ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS + ClassWriter.COMPUTE_FRAMES);
+        cw.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL + Opcodes.ACC_SUPER, className, null, superName, null);
+
+        MethodVisitor mv = cw.visitMethod(Opcodes.ACC_STATIC | Opcodes.ACC_PUBLIC, "test", "()V", null, null);
+        mv.visitMethodInsn(Opcodes.INVOKESTATIC, "p1/T", "test0", "()V", false);
+        mv.visitMethodInsn(Opcodes.INVOKESTATIC, "p1/T", "test1", "()V", false);
+        mv.visitMethodInsn(Opcodes.INVOKESTATIC, "p1/T", "test2", "()V", false);
+        mv.visitMethodInsn(Opcodes.INVOKESTATIC, "p1/T", "test3", "()V", false);
+        mv.visitInsn(Opcodes.RETURN);
+        mv.visitMaxs(0, 0);
+        mv.visitEnd();
+
+        final byte[] classBytes = cw.toByteArray();
+        Class<?> invokerClass = UNSAFE.defineAnonymousClass(hostClass, classBytes, new Object[0]);
+        UNSAFE.ensureClassInitialized(invokerClass);
+        return invokerClass;
+    }
+
+    public static void main(String[] args) throws Throwable {
+        Throwable fail = null;
+
+        // Anonymous class has the privileges of its host class, so test[0123] should all work.
+        System.out.println("Injecting from the same package (p1):");
+        Class<?> p1cls = getAnonClass(T.class, "p1/AnonClass");
+        try {
+            p1cls.getMethod("test").invoke(null);
+        } catch (Throwable ex) {
+            ex.printStackTrace();
+            fail = ex;  // throw this to make test fail, since subtest failed
+        }
+
+        // Anonymous class has different package name from host class.  Should throw
+        // IllegalArgumentException.
+        System.out.println("Injecting from the wrong package (p2):");
+        try {
+            Class<?> p2cls = getAnonClass(DefineAnon.class, "p2/AnonClass");
+            p2cls.getMethod("test").invoke(null);
+            System.out.println("Failed, did not get expected IllegalArgumentException");
+        } catch (java.lang.IllegalArgumentException e) {
+            if (e.getMessage().contains("Host class p1/DefineAnon and anonymous class p2/AnonClass")) {
+                System.out.println("Got expected IllegalArgumentException: " + e.getMessage());
+            } else {
+                throw new RuntimeException("Unexpected message: " + e.getMessage());
+            }
+        } catch (Throwable ex) {
+            ex.printStackTrace();
+            fail = ex;  // throw this to make test fail, since subtest failed
+        }
+
+        // Inject a class in the unnamed package into p1.T.  It should be able
+        // to access all methods in p1.T.
+        System.out.println("Injecting unnamed package into correct host class:");
+        try {
+            Class<?> p3cls = getAnonClass(T.class, "AnonClass");
+            p3cls.getMethod("test").invoke(null);
+        } catch (Throwable ex) {
+            ex.printStackTrace();
+            fail = ex;  // throw this to make test fail, since subtest failed
+        }
+
+        // Try using an array class as the host class.  This should throw IllegalArgumentException.
+        try {
+            Class<?> p3cls = getAnonClass(String[].class, "AnonClass");
+            throw new RuntimeException("Expected IllegalArgumentException not thrown");
+        } catch (IllegalArgumentException ex) {
+        }
+
+        if (fail != null) throw fail;  // make test fail, since subtest failed
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/defineAnonClass/NestedUnsafe.java	Fri Sep 09 06:44:31 2016 +0000
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8058575
+ * @summary Creates an anonymous class inside of an anonymous class.
+ * @library /test/lib
+ * @modules java.base/jdk.internal.misc
+ *          java.compiler
+ *          java.management
+ * @run main p.NestedUnsafe
+ */
+
+package p;
+
+import java.security.ProtectionDomain;
+import java.io.InputStream;
+import java.lang.*;
+import jdk.test.lib.*;
+import jdk.internal.misc.Unsafe;
+import jdk.test.lib.unsafe.UnsafeHelper;
+
+
+// Test that an anonymous class in package 'p' cannot define its own anonymous class
+// in another package.
+public class NestedUnsafe {
+    // The String concatenation should create the nested anonymous class.
+    static byte klassbuf[] = InMemoryJavaCompiler.compile("q.TestClass",
+        "package q; " +
+        "public class TestClass { " +
+        "    public static void concat(String one, String two) throws Throwable { " +
+        "        System.out.println(one + two);" +
+        " } } ");
+
+    public static void main(String args[]) throws Exception {
+        Unsafe unsafe = UnsafeHelper.getUnsafe();
+
+        // The anonymous class calls defineAnonymousClass creating a nested anonymous class.
+        byte klassbuf2[] = InMemoryJavaCompiler.compile("p.TestClass2",
+            "package p; " +
+            "import jdk.internal.misc.Unsafe; " +
+            "public class TestClass2 { " +
+            "    public static void doit() throws Throwable { " +
+            "        Unsafe unsafe = jdk.internal.misc.Unsafe.getUnsafe(); " +
+            "        Class klass2 = unsafe.defineAnonymousClass(TestClass2.class, p.NestedUnsafe.klassbuf, new Object[0]); " +
+            "        unsafe.ensureClassInitialized(klass2); " +
+            "        Class[] dArgs = new Class[2]; " +
+            "        dArgs[0] = String.class; " +
+            "        dArgs[1] = String.class; " +
+            "        try { " +
+            "            klass2.getMethod(\"concat\", dArgs).invoke(null, \"CC\", \"DD\"); " +
+            "        } catch (Throwable ex) { " +
+            "            throw new RuntimeException(\"Exception: \" + ex.toString()); " +
+            "        } " +
+            "} } ",
+            "--add-exports=java.base/jdk.internal.misc=ALL-UNNAMED");
+
+        Class klass2 = unsafe.defineAnonymousClass(p.NestedUnsafe.class, klassbuf2, new Object[0]);
+        try {
+            klass2.getMethod("doit").invoke(null);
+            throw new RuntimeException("Expected exception not thrown");
+        } catch (Throwable ex) {
+            Throwable iae = ex.getCause();
+            if (!iae.toString().contains(
+                "IllegalArgumentException: Host class p/NestedUnsafe and anonymous class q/TestClass")) {
+                throw new RuntimeException("Exception: " + iae.toString());
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/defineAnonClass/NestedUnsafe2.java	Fri Sep 09 06:44:31 2016 +0000
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8058575
+ * @summary Creates an anonymous class inside of an anonymous class.
+ * @library /test/lib
+ * @modules java.base/jdk.internal.misc
+ *          java.compiler
+ *          java.management
+ * @run main p.NestedUnsafe2
+ */
+
+package p;
+
+import java.security.ProtectionDomain;
+import java.io.InputStream;
+import java.lang.*;
+import jdk.test.lib.*;
+import jdk.internal.misc.Unsafe;
+import jdk.test.lib.unsafe.UnsafeHelper;
+
+
+// Test that an anonymous class that gets put in its host's package cannot define
+// an anonymous class in another package.
+public class NestedUnsafe2 {
+    // The String concatenation should create the nested anonymous class.
+    public static byte klassbuf[] = InMemoryJavaCompiler.compile("q.TestClass",
+        "package q; " +
+        "public class TestClass { " +
+        "    public static void concat(String one, String two) throws Throwable { " +
+        "        System.out.println(one + two);" +
+        " } } ");
+
+    public static void main(String args[]) throws Exception {
+        Unsafe unsafe = UnsafeHelper.getUnsafe();
+
+        // The anonymous class calls defineAnonymousClass creating a nested anonymous class.
+        byte klassbuf2[] = InMemoryJavaCompiler.compile("TestClass2",
+            "import jdk.internal.misc.Unsafe; " +
+            "public class TestClass2 { " +
+            "    public static void doit() throws Throwable { " +
+            "        Unsafe unsafe = jdk.internal.misc.Unsafe.getUnsafe(); " +
+            "        Class klass2 = unsafe.defineAnonymousClass(TestClass2.class, p.NestedUnsafe2.klassbuf, new Object[0]); " +
+            "        unsafe.ensureClassInitialized(klass2); " +
+            "        Class[] dArgs = new Class[2]; " +
+            "        dArgs[0] = String.class; " +
+            "        dArgs[1] = String.class; " +
+            "        try { " +
+            "            klass2.getMethod(\"concat\", dArgs).invoke(null, \"CC\", \"DD\"); " +
+            "        } catch (Throwable ex) { " +
+            "            throw new RuntimeException(\"Exception: \" + ex.toString()); " +
+            "        } " +
+            "} } ",
+            "--add-exports=java.base/jdk.internal.misc=ALL-UNNAMED");
+
+        Class klass2 = unsafe.defineAnonymousClass(p.NestedUnsafe2.class, klassbuf2, new Object[0]);
+        try {
+            klass2.getMethod("doit").invoke(null);
+            throw new RuntimeException("Expected exception not thrown");
+        } catch (Throwable ex) {
+            Throwable iae = ex.getCause();
+            if (!iae.toString().contains(
+                "IllegalArgumentException: Host class p/NestedUnsafe2 and anonymous class q/TestClass")) {
+                throw new RuntimeException("Exception: " + iae.toString());
+            }
+        }
+    }
+}
--- a/hotspot/test/testlibrary/ctw/Makefile	Thu Sep 08 23:38:56 2016 -0700
+++ b/hotspot/test/testlibrary/ctw/Makefile	Fri Sep 09 06:44:31 2016 +0000
@@ -40,7 +40,7 @@
 JAVAC = $(JDK_HOME)/bin/javac
 JAR = $(JDK_HOME)/bin/jar
 
-SRC_FILES = $(shell find $(SRC_DIR) $(TESTLIBRARY_DIR)/share/classes -name '*.java')
+SRC_FILES = $(shell find $(SRC_DIR) $(TESTLIBRARY_DIR)/jdk/test/lib -name '*.java')
 WB_SRC_FILES = $(shell find $(TESTLIBRARY_DIR)/sun/hotspot -name '*.java')
 
 MAIN_CLASS = sun.hotspot.tools.ctw.CompileTheWorld
--- a/hotspot/test/testlibrary/jittester/Makefile	Thu Sep 08 23:38:56 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/Makefile	Fri Sep 09 06:44:31 2016 +0000
@@ -56,7 +56,6 @@
 CLASSES_DIR = $(BUILD_DIR)/classes
 SRC_DIR = src
 TEST_DIR = test
-DRIVER_DIR = $(TESTBASE_DIR)/jdk/test/lib/jittester/jtreg
 MANIFEST = manifest.mf
 APPLICATION_ARGS += \
     --property-file $(PROPERTY_FILE) \
@@ -118,19 +117,18 @@
 	@rm filelist
 	@rm -rf $(CLASSES_DIR)
 
-copytestlibrary: $(DRIVER_DIR)
-	@cp -r src/jdk/test/lib/jittester/jtreg/*.java $(DRIVER_DIR)
+copytestlibrary: $(TESTBASE_DIR)/jdk/test/lib/jittester/jtreg
+	@cp -r src/jdk/test/lib/jittester/jtreg/*.java $(TESTBASE_DIR)/jdk/test/lib/jittester/jtreg
+	@cp -r $(TESTLIBRARY_SRC_DIR) $(TESTBASE_DIR)/jdk/test/
 
 testgroup: $(TESTBASE_DIR)
 	@echo 'jittester_all = \\' > $(TESTGROUP_FILE)
 	@echo '	/' >> $(TESTGROUP_FILE)
 	@echo '' >> $(TESTGROUP_FILE)
-	@echo 'main = \\' >> $(TESTGROUP_FILE)
-	@echo '	Test_0.java' >> $(TESTGROUP_FILE)
 
 testroot: $(TESTBASE_DIR)
 	@echo 'groups=TEST.groups' > $(TESTROOT_FILE)
 
-$(TESTBASE_DIR) $(DIST_DIR) $(DRIVER_DIR):
+$(TESTBASE_DIR) $(DIST_DIR) $(TESTBASE_DIR)/jdk/test/lib/jittester/jtreg:
 	$(shell if [ ! -d $@ ]; then mkdir -p $@; fi)