8154580: Save mirror in interpreter frame to enable cleanups of CLDClosure
authorcoleenp
Mon, 25 Apr 2016 09:51:00 -0400
changeset 38074 8475fdc6dcc3
parent 38071 cdc19fb67395
child 38075 b573087c2812
8154580: Save mirror in interpreter frame to enable cleanups of CLDClosure Summary: GC walks the mirror using OopClosure rather than using CLDClosure in oops_interpreted_do() Reviewed-by: dlong, twisti, stefank
hotspot/src/cpu/aarch64/vm/abstractInterpreter_aarch64.cpp
hotspot/src/cpu/aarch64/vm/frame_aarch64.hpp
hotspot/src/cpu/aarch64/vm/frame_aarch64.inline.hpp
hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp
hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.hpp
hotspot/src/cpu/aarch64/vm/templateInterpreterGenerator_aarch64.cpp
hotspot/src/cpu/ppc/vm/abstractInterpreter_ppc.cpp
hotspot/src/cpu/ppc/vm/frame_ppc.hpp
hotspot/src/cpu/ppc/vm/frame_ppc.inline.hpp
hotspot/src/cpu/ppc/vm/macroAssembler_ppc.cpp
hotspot/src/cpu/ppc/vm/macroAssembler_ppc.hpp
hotspot/src/cpu/ppc/vm/templateInterpreterGenerator_ppc.cpp
hotspot/src/cpu/sparc/vm/abstractInterpreter_sparc.cpp
hotspot/src/cpu/sparc/vm/frame_sparc.cpp
hotspot/src/cpu/sparc/vm/frame_sparc.hpp
hotspot/src/cpu/sparc/vm/frame_sparc.inline.hpp
hotspot/src/cpu/sparc/vm/macroAssembler_sparc.cpp
hotspot/src/cpu/sparc/vm/macroAssembler_sparc.hpp
hotspot/src/cpu/sparc/vm/templateInterpreterGenerator_sparc.cpp
hotspot/src/cpu/x86/vm/abstractInterpreter_x86.cpp
hotspot/src/cpu/x86/vm/frame_x86.cpp
hotspot/src/cpu/x86/vm/frame_x86.hpp
hotspot/src/cpu/x86/vm/frame_x86.inline.hpp
hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp
hotspot/src/cpu/x86/vm/macroAssembler_x86.hpp
hotspot/src/cpu/x86/vm/templateInterpreterGenerator_x86.cpp
hotspot/src/cpu/zero/vm/bytecodeInterpreter_zero.cpp
hotspot/src/cpu/zero/vm/bytecodeInterpreter_zero.hpp
hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp
hotspot/src/cpu/zero/vm/frame_zero.inline.hpp
hotspot/src/share/vm/gc/g1/g1RootClosures.cpp
hotspot/src/share/vm/gc/g1/g1RootClosures.hpp
hotspot/src/share/vm/gc/g1/g1RootProcessor.cpp
hotspot/src/share/vm/gc/parallel/pcTasks.cpp
hotspot/src/share/vm/gc/parallel/psMarkSweep.cpp
hotspot/src/share/vm/gc/parallel/psParallelCompact.cpp
hotspot/src/share/vm/gc/parallel/psTasks.cpp
hotspot/src/share/vm/gc/shared/genCollectedHeap.cpp
hotspot/src/share/vm/interpreter/bytecodeInterpreter.hpp
hotspot/src/share/vm/runtime/deoptimization.cpp
hotspot/src/share/vm/runtime/frame.cpp
hotspot/src/share/vm/runtime/frame.hpp
hotspot/src/share/vm/runtime/thread.cpp
hotspot/src/share/vm/runtime/thread.hpp
hotspot/src/share/vm/runtime/vmThread.cpp
hotspot/src/share/vm/runtime/vmThread.hpp
hotspot/test/TEST.groups
hotspot/test/runtime/8003720/Asmator.java
hotspot/test/runtime/8003720/Test8003720.java
hotspot/test/runtime/8003720/Victim.java
hotspot/test/runtime/8003720/VictimClassLoader.java
hotspot/test/runtime/MirrorFrame/Asmator.java
hotspot/test/runtime/MirrorFrame/Test8003720.java
hotspot/test/runtime/MirrorFrame/Victim.java
hotspot/test/runtime/MirrorFrame/VictimClassLoader.java
--- a/hotspot/src/cpu/aarch64/vm/abstractInterpreter_aarch64.cpp	Mon Apr 25 11:36:14 2016 +0200
+++ b/hotspot/src/cpu/aarch64/vm/abstractInterpreter_aarch64.cpp	Mon Apr 25 09:51:00 2016 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
  * Copyright (c) 2014, Red Hat Inc. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -177,4 +177,6 @@
   }
   *interpreter_frame->interpreter_frame_cache_addr() =
     method->constants()->cache();
+  *interpreter_frame->interpreter_frame_mirror_addr() =
+    method->method_holder()->java_mirror();
 }
--- a/hotspot/src/cpu/aarch64/vm/frame_aarch64.hpp	Mon Apr 25 11:36:14 2016 +0200
+++ b/hotspot/src/cpu/aarch64/vm/frame_aarch64.hpp	Mon Apr 25 09:51:00 2016 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
  * Copyright (c) 2014, Red Hat Inc. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -78,7 +78,9 @@
     interpreter_frame_last_sp_offset                 = interpreter_frame_sender_sp_offset - 1,
     interpreter_frame_method_offset                  = interpreter_frame_last_sp_offset - 1,
     interpreter_frame_mdp_offset                     = interpreter_frame_method_offset - 1,
-    interpreter_frame_cache_offset                   = interpreter_frame_mdp_offset - 1,
+    interpreter_frame_padding_offset                 = interpreter_frame_mdp_offset - 1,
+    interpreter_frame_mirror_offset                  = interpreter_frame_padding_offset - 1,
+    interpreter_frame_cache_offset                   = interpreter_frame_mirror_offset - 1,
     interpreter_frame_locals_offset                  = interpreter_frame_cache_offset - 1,
     interpreter_frame_bcp_offset                     = interpreter_frame_locals_offset - 1,
     interpreter_frame_initial_sp_offset              = interpreter_frame_bcp_offset - 1,
--- a/hotspot/src/cpu/aarch64/vm/frame_aarch64.inline.hpp	Mon Apr 25 11:36:14 2016 +0200
+++ b/hotspot/src/cpu/aarch64/vm/frame_aarch64.inline.hpp	Mon Apr 25 09:51:00 2016 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
  * Copyright (c) 2014, Red Hat Inc. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -188,6 +188,12 @@
   return (Method**)addr_at(interpreter_frame_method_offset);
 }
 
+// Mirror
+
+inline oop* frame::interpreter_frame_mirror_addr() const {
+  return (oop*)addr_at(interpreter_frame_mirror_offset);
+}
+
 // top of expression stack
 inline intptr_t* frame::interpreter_frame_tos_address() const {
   intptr_t* last_sp = interpreter_frame_last_sp();
--- a/hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp	Mon Apr 25 11:36:14 2016 +0200
+++ b/hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp	Mon Apr 25 09:51:00 2016 -0400
@@ -3217,6 +3217,14 @@
   }
 }
 
+void MacroAssembler::load_mirror(Register dst, Register method) {
+  const int mirror_offset = in_bytes(Klass::java_mirror_offset());
+  ldr(dst, Address(rmethod, Method::const_offset()));
+  ldr(dst, Address(dst, ConstMethod::constants_offset()));
+  ldr(dst, Address(dst, ConstantPool::pool_holder_offset_in_bytes()));
+  ldr(dst, Address(dst, mirror_offset));
+}
+
 void MacroAssembler::cmp_klass(Register oop, Register trial_klass, Register tmp) {
   if (UseCompressedClassPointers) {
     ldrw(tmp, Address(oop, oopDesc::klass_offset_in_bytes()));
--- a/hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.hpp	Mon Apr 25 11:36:14 2016 +0200
+++ b/hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.hpp	Mon Apr 25 09:51:00 2016 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
  * Copyright (c) 2014, 2015, Red Hat Inc. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -770,6 +770,8 @@
   void store_klass(Register dst, Register src);
   void cmp_klass(Register oop, Register trial_klass, Register tmp);
 
+  void load_mirror(Register dst, Register method);
+
   void load_heap_oop(Register dst, Address src);
 
   void load_heap_oop_not_null(Register dst, Address src);
--- a/hotspot/src/cpu/aarch64/vm/templateInterpreterGenerator_aarch64.cpp	Mon Apr 25 11:36:14 2016 +0200
+++ b/hotspot/src/cpu/aarch64/vm/templateInterpreterGenerator_aarch64.cpp	Mon Apr 25 09:51:00 2016 -0400
@@ -759,18 +759,13 @@
 
   // get synchronization object
   {
-    const int mirror_offset = in_bytes(Klass::java_mirror_offset());
     Label done;
     __ ldrw(r0, access_flags);
     __ tst(r0, JVM_ACC_STATIC);
     // get receiver (assume this is frequent case)
     __ ldr(r0, Address(rlocals, Interpreter::local_offset_in_bytes(0)));
     __ br(Assembler::EQ, done);
-    __ ldr(r0, Address(rmethod, Method::const_offset()));
-    __ ldr(r0, Address(r0, ConstMethod::constants_offset()));
-    __ ldr(r0, Address(r0,
-                           ConstantPool::pool_holder_offset_in_bytes()));
-    __ ldr(r0, Address(r0, mirror_offset));
+    __ load_mirror(r0, rmethod);
 
 #ifdef ASSERT
     {
@@ -807,16 +802,16 @@
 void TemplateInterpreterGenerator::generate_fixed_frame(bool native_call) {
   // initialize fixed part of activation frame
   if (native_call) {
-    __ sub(esp, sp, 12 *  wordSize);
+    __ sub(esp, sp, 14 *  wordSize);
     __ mov(rbcp, zr);
-    __ stp(esp, zr, Address(__ pre(sp, -12 * wordSize)));
+    __ stp(esp, zr, Address(__ pre(sp, -14 * wordSize)));
     // add 2 zero-initialized slots for native calls
-    __ stp(zr, zr, Address(sp, 10 * wordSize));
+    __ stp(zr, zr, Address(sp, 12 * wordSize));
   } else {
-    __ sub(esp, sp, 10 *  wordSize);
+    __ sub(esp, sp, 12 *  wordSize);
     __ ldr(rscratch1, Address(rmethod, Method::const_offset()));      // get ConstMethod
     __ add(rbcp, rscratch1, in_bytes(ConstMethod::codes_offset())); // get codebase
-    __ stp(esp, rbcp, Address(__ pre(sp, -10 * wordSize)));
+    __ stp(esp, rbcp, Address(__ pre(sp, -12 * wordSize)));
   }
 
   if (ProfileInterpreter) {
@@ -825,22 +820,26 @@
     __ cbz(rscratch1, method_data_continue);
     __ lea(rscratch1, Address(rscratch1, in_bytes(MethodData::data_offset())));
     __ bind(method_data_continue);
-    __ stp(rscratch1, rmethod, Address(sp, 4 * wordSize));  // save Method* and mdp (method data pointer)
+    __ stp(rscratch1, rmethod, Address(sp, 6 * wordSize));  // save Method* and mdp (method data pointer)
   } else {
-    __ stp(zr, rmethod, Address(sp, 4 * wordSize));        // save Method* (no mdp)
+    __ stp(zr, rmethod, Address(sp, 6 * wordSize));        // save Method* (no mdp)
   }
 
+  // Get mirror and store it in the frame as GC root for this Method*
+  __ load_mirror(rscratch1, rmethod);
+  __ stp(rscratch1, zr, Address(sp, 4 * wordSize));
+
   __ ldr(rcpool, Address(rmethod, Method::const_offset()));
   __ ldr(rcpool, Address(rcpool, ConstMethod::constants_offset()));
   __ ldr(rcpool, Address(rcpool, ConstantPool::cache_offset_in_bytes()));
   __ stp(rlocals, rcpool, Address(sp, 2 * wordSize));
 
-  __ stp(rfp, lr, Address(sp, 8 * wordSize));
-  __ lea(rfp, Address(sp, 8 * wordSize));
+  __ stp(rfp, lr, Address(sp, 10 * wordSize));
+  __ lea(rfp, Address(sp, 10 * wordSize));
 
   // set sender sp
   // leave last_sp as null
-  __ stp(zr, r13, Address(sp, 6 * wordSize));
+  __ stp(zr, r13, Address(sp, 8 * wordSize));
 
   // Move SP out of the way
   if (! native_call) {
@@ -1242,15 +1241,11 @@
   // pass mirror handle if static call
   {
     Label L;
-    const int mirror_offset = in_bytes(Klass::java_mirror_offset());
     __ ldrw(t, Address(rmethod, Method::access_flags_offset()));
     __ tst(t, JVM_ACC_STATIC);
     __ br(Assembler::EQ, L);
     // get mirror
-    __ ldr(t, Address(rmethod, Method::const_offset()));
-    __ ldr(t, Address(t, ConstMethod::constants_offset()));
-    __ ldr(t, Address(t, ConstantPool::pool_holder_offset_in_bytes()));
-    __ ldr(t, Address(t, mirror_offset));
+    __ load_mirror(t, rmethod);
     // copy mirror into activation frame
     __ str(t, Address(rfp, frame::interpreter_frame_oop_temp_offset * wordSize));
     // pass handle to mirror
--- a/hotspot/src/cpu/ppc/vm/abstractInterpreter_ppc.cpp	Mon Apr 25 11:36:14 2016 +0200
+++ b/hotspot/src/cpu/ppc/vm/abstractInterpreter_ppc.cpp	Mon Apr 25 09:51:00 2016 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
  * Copyright (c) 2015 SAP SE. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -152,6 +152,7 @@
   intptr_t* top_frame_sp = is_top_frame ? sp : sp + (frame::abi_minframe_size - frame::abi_reg_args_size) / Interpreter::stackElementSize;
 
   interpreter_frame->interpreter_frame_set_method(method);
+  interpreter_frame->interpreter_frame_set_mirror(method->method_holder()->java_mirror());
   interpreter_frame->interpreter_frame_set_locals(locals_base);
   interpreter_frame->interpreter_frame_set_cpcache(method->constants()->cache());
   interpreter_frame->interpreter_frame_set_esp(esp);
--- a/hotspot/src/cpu/ppc/vm/frame_ppc.hpp	Mon Apr 25 11:36:14 2016 +0200
+++ b/hotspot/src/cpu/ppc/vm/frame_ppc.hpp	Mon Apr 25 09:51:00 2016 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
  * Copyright (c) 2012, 2015 SAP SE. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -261,6 +261,7 @@
     uint64_t ijava_reserved2; // Inserted for alignment.
 #endif
     uint64_t method;
+    uint64_t mirror;
     uint64_t locals;
     uint64_t monitors;
     uint64_t cpoolCache;
--- a/hotspot/src/cpu/ppc/vm/frame_ppc.inline.hpp	Mon Apr 25 11:36:14 2016 +0200
+++ b/hotspot/src/cpu/ppc/vm/frame_ppc.inline.hpp	Mon Apr 25 09:51:00 2016 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
  * Copyright (c) 2012, 2015 SAP SE. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -148,6 +148,11 @@
 inline Method** frame::interpreter_frame_method_addr() const {
   return (Method**) &(get_ijava_state()->method);
 }
+
+inline oop* frame::interpreter_frame_mirror_addr() const {
+  return (oop*) &(get_ijava_state()->mirror);
+}
+
 inline ConstantPoolCache** frame::interpreter_frame_cpoolcache_addr() const {
   return (ConstantPoolCache**) &(get_ijava_state()->cpoolCache);
 }
--- a/hotspot/src/cpu/ppc/vm/macroAssembler_ppc.cpp	Mon Apr 25 11:36:14 2016 +0200
+++ b/hotspot/src/cpu/ppc/vm/macroAssembler_ppc.cpp	Mon Apr 25 09:51:00 2016 -0400
@@ -3118,6 +3118,14 @@
   }
 }
 
+void MacroAssembler::load_mirror(Register mirror, Register method) {
+  const int mirror_offset = in_bytes(Klass::java_mirror_offset());
+  ld(mirror, in_bytes(Method::const_offset()), method);
+  ld(mirror, in_bytes(ConstMethod::constants_offset()), mirror);
+  ld(mirror, ConstantPool::pool_holder_offset_in_bytes(), mirror);
+  ld(mirror, mirror_offset, mirror);
+}
+
 // Clear Array
 // Kills both input registers. tmp == R0 is allowed.
 void MacroAssembler::clear_memory_doubleword(Register base_ptr, Register cnt_dwords, Register tmp) {
--- a/hotspot/src/cpu/ppc/vm/macroAssembler_ppc.hpp	Mon Apr 25 11:36:14 2016 +0200
+++ b/hotspot/src/cpu/ppc/vm/macroAssembler_ppc.hpp	Mon Apr 25 09:51:00 2016 -0400
@@ -647,6 +647,9 @@
   void load_klass(Register dst, Register src);
   void store_klass(Register dst_oop, Register klass, Register tmp = R0);
   void store_klass_gap(Register dst_oop, Register val = noreg); // Will store 0 if val not specified.
+
+  void load_mirror(Register mirror, Register method);
+
   static int instr_size_for_decode_klass_not_null();
   void decode_klass_not_null(Register dst, Register src = noreg);
   Register encode_klass_not_null(Register dst, Register src = noreg);
--- a/hotspot/src/cpu/ppc/vm/templateInterpreterGenerator_ppc.cpp	Mon Apr 25 11:36:14 2016 +0200
+++ b/hotspot/src/cpu/ppc/vm/templateInterpreterGenerator_ppc.cpp	Mon Apr 25 09:51:00 2016 -0400
@@ -869,7 +869,6 @@
 
   // Get synchronization object to Rscratch2.
   {
-    const int mirror_offset = in_bytes(Klass::java_mirror_offset());
     Label Lstatic;
     Label Ldone;
 
@@ -881,10 +880,7 @@
     __ b(Ldone);
 
     __ bind(Lstatic); // Static case: Lock the java mirror
-    __ ld(Robj_to_lock, in_bytes(Method::const_offset()), R19_method);
-    __ ld(Robj_to_lock, in_bytes(ConstMethod::constants_offset()), Robj_to_lock);
-    __ ld(Robj_to_lock, ConstantPool::pool_holder_offset_in_bytes(), Robj_to_lock);
-    __ ld(Robj_to_lock, mirror_offset, Robj_to_lock);
+    __ load_mirror(Robj_to_lock, R19_method);
 
     __ bind(Ldone);
     __ verify_oop(Robj_to_lock);
@@ -1049,10 +1045,14 @@
   __ addi(R26_monitor, R1_SP, - frame::ijava_state_size);
   __ addi(R15_esp, R26_monitor, - Interpreter::stackElementSize);
 
+  // Get mirror and store it in the frame as GC root for this Method*
+  __ load_mirror(R12_scratch2, R19_method);
+
   // Store values.
   // R15_esp, R14_bcp, R26_monitor, R28_mdx are saved at java calls
   // in InterpreterMacroAssembler::call_from_interpreter.
   __ std(R19_method, _ijava_state_neg(method), R1_SP);
+  __ std(R12_scratch2, _ijava_state_neg(mirror), R1_SP);
   __ std(R21_sender_SP, _ijava_state_neg(sender_sp), R1_SP);
   __ std(R27_constPoolCache, _ijava_state_neg(cpoolCache), R1_SP);
   __ std(R18_locals, _ijava_state_neg(locals), R1_SP);
@@ -1317,21 +1317,11 @@
     __ testbitdi(CCR0, R0, access_flags, JVM_ACC_STATIC_BIT);
     __ bfalse(CCR0, method_is_not_static);
 
-    // constants = method->constants();
-    __ ld(R11_scratch1, in_bytes(Method::const_offset()), R19_method);
-    __ ld(R11_scratch1, in_bytes(ConstMethod::constants_offset()), R11_scratch1);
-    // pool_holder = method->constants()->pool_holder();
-    __ ld(R11_scratch1/*pool_holder*/, ConstantPool::pool_holder_offset_in_bytes(),
-          R11_scratch1/*constants*/);
-
-    const int mirror_offset = in_bytes(Klass::java_mirror_offset());
-
-    // mirror = pool_holder->klass_part()->java_mirror();
-    __ ld(R0/*mirror*/, mirror_offset, R11_scratch1/*pool_holder*/);
+    __ load_mirror(R12_sratch2, R19_method);
     // state->_native_mirror = mirror;
 
     __ ld(R11_scratch1, 0, R1_SP);
-    __ std(R0/*mirror*/, _ijava_state_neg(oop_tmp), R11_scratch1);
+    __ std(R12_scratch2/*mirror*/, _ijava_state_neg(oop_tmp), R11_scratch1);
     // R4_ARG2 = &state->_oop_temp;
     __ addi(R4_ARG2, R11_scratch1, _ijava_state_neg(oop_tmp));
     BIND(method_is_not_static);
--- a/hotspot/src/cpu/sparc/vm/abstractInterpreter_sparc.cpp	Mon Apr 25 11:36:14 2016 +0200
+++ b/hotspot/src/cpu/sparc/vm/abstractInterpreter_sparc.cpp	Mon Apr 25 09:51:00 2016 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -281,11 +281,12 @@
   // Llast_SP will be same as SP as there is no adapter space
   *interpreter_frame->register_addr(Llast_SP)    = (intptr_t) interpreter_frame->sp() - STACK_BIAS;
   *interpreter_frame->register_addr(LcpoolCache) = (intptr_t) method->constants()->cache();
+  // save the mirror in the interpreter frame
+  *interpreter_frame->interpreter_frame_mirror_addr() = method->method_holder()->java_mirror();
 #ifdef FAST_DISPATCH
   *interpreter_frame->register_addr(IdispatchTables) = (intptr_t) Interpreter::dispatch_table();
 #endif
 
-
 #ifdef ASSERT
   BasicObjectLock* mp = (BasicObjectLock*)monitors;
 
--- a/hotspot/src/cpu/sparc/vm/frame_sparc.cpp	Mon Apr 25 11:36:14 2016 +0200
+++ b/hotspot/src/cpu/sparc/vm/frame_sparc.cpp	Mon Apr 25 09:51:00 2016 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -783,7 +783,7 @@
   if (is_interpreted_frame()) {
     DESCRIBE_FP_OFFSET(interpreter_frame_d_scratch_fp);
     DESCRIBE_FP_OFFSET(interpreter_frame_l_scratch_fp);
-    DESCRIBE_FP_OFFSET(interpreter_frame_padding);
+    DESCRIBE_FP_OFFSET(interpreter_frame_mirror);
     DESCRIBE_FP_OFFSET(interpreter_frame_oop_temp);
 
     // esp, according to Lesp (e.g. not depending on bci), if seems valid
--- a/hotspot/src/cpu/sparc/vm/frame_sparc.hpp	Mon Apr 25 11:36:14 2016 +0200
+++ b/hotspot/src/cpu/sparc/vm/frame_sparc.hpp	Mon Apr 25 09:51:00 2016 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -209,7 +209,8 @@
        // 2 words, also used to save float regs across  calls to C
        interpreter_frame_d_scratch_fp_offset          = -2,
        interpreter_frame_l_scratch_fp_offset          = -4,
-       interpreter_frame_padding_offset               = -5, // for native calls only
+       interpreter_frame_mirror_offset                = -5, // keep interpreted method alive
+
        interpreter_frame_oop_temp_offset              = -6, // for native calls only
        interpreter_frame_vm_locals_fp_offset          = -6, // should be same as above, and should be zero mod 8
 
--- a/hotspot/src/cpu/sparc/vm/frame_sparc.inline.hpp	Mon Apr 25 11:36:14 2016 +0200
+++ b/hotspot/src/cpu/sparc/vm/frame_sparc.inline.hpp	Mon Apr 25 09:51:00 2016 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -163,6 +163,10 @@
   *interpreter_frame_monitors_addr() = monitors;
 }
 
+inline oop* frame::interpreter_frame_mirror_addr() const {
+  return (oop*)(fp() + interpreter_frame_mirror_offset);
+}
+
 // Constant pool cache
 
 // where LcpoolCache is saved:
--- a/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.cpp	Mon Apr 25 11:36:14 2016 +0200
+++ b/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.cpp	Mon Apr 25 09:51:00 2016 -0400
@@ -3972,6 +3972,14 @@
   card_table_write(bs->byte_map_base, tmp, store_addr);
 }
 
+void MacroAssembler::load_mirror(Register mirror, Register method) {
+  const int mirror_offset = in_bytes(Klass::java_mirror_offset());
+  ld_ptr(method, in_bytes(Method::const_offset()), mirror);
+  ld_ptr(mirror, in_bytes(ConstMethod::constants_offset()), mirror);
+  ld_ptr(mirror, ConstantPool::pool_holder_offset_in_bytes(), mirror);
+  ld_ptr(mirror, mirror_offset, mirror);
+}
+
 void MacroAssembler::load_klass(Register src_oop, Register klass) {
   // The number of bytes in this code is used by
   // MachCallDynamicJavaNode::ret_addr_offset()
--- a/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.hpp	Mon Apr 25 11:36:14 2016 +0200
+++ b/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.hpp	Mon Apr 25 09:51:00 2016 -0400
@@ -1012,6 +1012,8 @@
   inline void ldbool(const Address& a, Register d);
   inline void movbool( bool boolconst, Register d);
 
+  void load_mirror(Register mirror, Register method);
+
   // klass oop manipulations if compressed
   void load_klass(Register src_oop, Register klass);
   void store_klass(Register klass, Register dst_oop);
--- a/hotspot/src/cpu/sparc/vm/templateInterpreterGenerator_sparc.cpp	Mon Apr 25 11:36:14 2016 +0200
+++ b/hotspot/src/cpu/sparc/vm/templateInterpreterGenerator_sparc.cpp	Mon Apr 25 09:51:00 2016 -0400
@@ -557,17 +557,12 @@
 
   // get synchronization object to O0
   { Label done;
-    const int mirror_offset = in_bytes(Klass::java_mirror_offset());
     __ btst(JVM_ACC_STATIC, O0);
     __ br( Assembler::zero, true, Assembler::pt, done);
     __ delayed()->ld_ptr(Llocals, Interpreter::local_offset_in_bytes(0), O0); // get receiver for not-static case
 
-    __ ld_ptr( Lmethod, in_bytes(Method::const_offset()), O0);
-    __ ld_ptr( O0, in_bytes(ConstMethod::constants_offset()), O0);
-    __ ld_ptr( O0, ConstantPool::pool_holder_offset_in_bytes(), O0);
-
     // lock the mirror, not the Klass*
-    __ ld_ptr( O0, mirror_offset, O0);
+    __ load_mirror(O0, Lmethod);
 
 #ifdef ASSERT
     __ tst(O0);
@@ -881,6 +876,10 @@
     __ add(Lbcp, in_bytes(ConstMethod::codes_offset()), Lbcp);
   }
   __ mov( G5_method, Lmethod);                 // set Lmethod
+  // Get mirror and store it in the frame as GC root for this Method*
+  Register mirror = LcpoolCache;
+  __ load_mirror(mirror, Lmethod);
+  __ st_ptr(mirror, FP, (frame::interpreter_frame_mirror_offset * wordSize) + STACK_BIAS);
   __ get_constant_pool_cache( LcpoolCache );   // set LcpoolCache
   __ sub(FP, rounded_vm_local_words * BytesPerWord, Lmonitors ); // set Lmonitors
 #ifdef _LP64
@@ -1297,12 +1296,7 @@
     // get native function entry point(O0 is a good temp until the very end)
     __ delayed()->ld_ptr(Lmethod, in_bytes(Method::native_function_offset()), O0);
     // for static methods insert the mirror argument
-    const int mirror_offset = in_bytes(Klass::java_mirror_offset());
-
-    __ ld_ptr(Lmethod, Method:: const_offset(), O1);
-    __ ld_ptr(O1, ConstMethod::constants_offset(), O1);
-    __ ld_ptr(O1, ConstantPool::pool_holder_offset_in_bytes(), O1);
-    __ ld_ptr(O1, mirror_offset, O1);
+    __ load_mirror(O1, Lmethod);
 #ifdef ASSERT
     if (!PrintSignatureHandlers)  // do not dirty the output with this
     { Label L;
--- a/hotspot/src/cpu/x86/vm/abstractInterpreter_x86.cpp	Mon Apr 25 11:36:14 2016 +0200
+++ b/hotspot/src/cpu/x86/vm/abstractInterpreter_x86.cpp	Mon Apr 25 09:51:00 2016 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -113,6 +113,8 @@
   }
   *interpreter_frame->interpreter_frame_cache_addr() =
     method->constants()->cache();
+  *interpreter_frame->interpreter_frame_mirror_addr() =
+    method->method_holder()->java_mirror();
 }
 
 #ifndef _LP64
--- a/hotspot/src/cpu/x86/vm/frame_x86.cpp	Mon Apr 25 11:36:14 2016 +0200
+++ b/hotspot/src/cpu/x86/vm/frame_x86.cpp	Mon Apr 25 09:51:00 2016 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -640,6 +640,7 @@
     DESCRIBE_FP_OFFSET(interpreter_frame_sender_sp);
     DESCRIBE_FP_OFFSET(interpreter_frame_last_sp);
     DESCRIBE_FP_OFFSET(interpreter_frame_method);
+    DESCRIBE_FP_OFFSET(interpreter_frame_mirror);
     DESCRIBE_FP_OFFSET(interpreter_frame_mdp);
     DESCRIBE_FP_OFFSET(interpreter_frame_cache);
     DESCRIBE_FP_OFFSET(interpreter_frame_locals);
--- a/hotspot/src/cpu/x86/vm/frame_x86.hpp	Mon Apr 25 11:36:14 2016 +0200
+++ b/hotspot/src/cpu/x86/vm/frame_x86.hpp	Mon Apr 25 09:51:00 2016 -0400
@@ -70,7 +70,8 @@
     // outgoing sp before a call to an invoked method
     interpreter_frame_last_sp_offset                 = interpreter_frame_sender_sp_offset - 1,
     interpreter_frame_method_offset                  = interpreter_frame_last_sp_offset - 1,
-    interpreter_frame_mdp_offset                     = interpreter_frame_method_offset - 1,
+    interpreter_frame_mirror_offset                  = interpreter_frame_method_offset - 1,
+    interpreter_frame_mdp_offset                     = interpreter_frame_mirror_offset - 1,
     interpreter_frame_cache_offset                   = interpreter_frame_mdp_offset - 1,
     interpreter_frame_locals_offset                  = interpreter_frame_cache_offset - 1,
     interpreter_frame_bcp_offset                     = interpreter_frame_locals_offset - 1,
--- a/hotspot/src/cpu/x86/vm/frame_x86.inline.hpp	Mon Apr 25 11:36:14 2016 +0200
+++ b/hotspot/src/cpu/x86/vm/frame_x86.inline.hpp	Mon Apr 25 09:51:00 2016 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -184,6 +184,12 @@
   return (Method**)addr_at(interpreter_frame_method_offset);
 }
 
+// Mirror
+
+inline oop* frame::interpreter_frame_mirror_addr() const {
+  return (oop*)addr_at(interpreter_frame_mirror_offset);
+}
+
 // top of expression stack
 inline intptr_t* frame::interpreter_frame_tos_address() const {
   intptr_t* last_sp = interpreter_frame_last_sp();
--- a/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp	Mon Apr 25 11:36:14 2016 +0200
+++ b/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp	Mon Apr 25 09:51:00 2016 -0400
@@ -6705,6 +6705,14 @@
 #endif // _LP64
 }
 
+void MacroAssembler::load_mirror(Register mirror, Register method) {
+  // get mirror
+  const int mirror_offset = in_bytes(Klass::java_mirror_offset());
+  movptr(mirror, Address(method, Method::const_offset()));
+  movptr(mirror, Address(mirror, ConstMethod::constants_offset()));
+  movptr(mirror, Address(mirror, ConstantPool::pool_holder_offset_in_bytes()));
+  movptr(mirror, Address(mirror, mirror_offset));
+}
 
 void MacroAssembler::load_klass(Register dst, Register src) {
 #ifdef _LP64
--- a/hotspot/src/cpu/x86/vm/macroAssembler_x86.hpp	Mon Apr 25 11:36:14 2016 +0200
+++ b/hotspot/src/cpu/x86/vm/macroAssembler_x86.hpp	Mon Apr 25 09:51:00 2016 -0400
@@ -323,6 +323,8 @@
   void movbool(Address dst, Register src);
   void testbool(Register dst);
 
+  void load_mirror(Register mirror, Register method);
+
   // oop manipulations
   void load_klass(Register dst, Register src);
   void store_klass(Register dst, Register src);
--- a/hotspot/src/cpu/x86/vm/templateInterpreterGenerator_x86.cpp	Mon Apr 25 11:36:14 2016 +0200
+++ b/hotspot/src/cpu/x86/vm/templateInterpreterGenerator_x86.cpp	Mon Apr 25 09:51:00 2016 -0400
@@ -608,18 +608,13 @@
 
   // get synchronization object
   {
-    const int mirror_offset = in_bytes(Klass::java_mirror_offset());
     Label done;
     __ movl(rax, access_flags);
     __ testl(rax, JVM_ACC_STATIC);
     // get receiver (assume this is frequent case)
     __ movptr(rax, Address(rlocals, Interpreter::local_offset_in_bytes(0)));
     __ jcc(Assembler::zero, done);
-    __ movptr(rax, Address(rbx, Method::const_offset()));
-    __ movptr(rax, Address(rax, ConstMethod::constants_offset()));
-    __ movptr(rax, Address(rax,
-                           ConstantPool::pool_holder_offset_in_bytes()));
-    __ movptr(rax, Address(rax, mirror_offset));
+    __ load_mirror(rax, rbx);
 
 #ifdef ASSERT
     {
@@ -662,6 +657,9 @@
   __ movptr(rbcp, Address(rbx, Method::const_offset()));      // get ConstMethod*
   __ lea(rbcp, Address(rbcp, ConstMethod::codes_offset())); // get codebase
   __ push(rbx);        // save Method*
+  // Get mirror and store it in the frame as GC root for this Method*
+  __ load_mirror(rdx, rbx);
+  __ push(rdx);
   if (ProfileInterpreter) {
     Label method_data_continue;
     __ movptr(rdx, Address(rbx, in_bytes(Method::method_data_offset())));
@@ -999,15 +997,11 @@
   // pass mirror handle if static call
   {
     Label L;
-    const int mirror_offset = in_bytes(Klass::java_mirror_offset());
     __ movl(t, Address(method, Method::access_flags_offset()));
     __ testl(t, JVM_ACC_STATIC);
     __ jcc(Assembler::zero, L);
     // get mirror
-    __ movptr(t, Address(method, Method::const_offset()));
-    __ movptr(t, Address(t, ConstMethod::constants_offset()));
-    __ movptr(t, Address(t, ConstantPool::pool_holder_offset_in_bytes()));
-    __ movptr(t, Address(t, mirror_offset));
+    __ load_mirror(t, method);
     // copy mirror into activation frame
     __ movptr(Address(rbp, frame::interpreter_frame_oop_temp_offset * wordSize),
             t);
--- a/hotspot/src/cpu/zero/vm/bytecodeInterpreter_zero.cpp	Mon Apr 25 11:36:14 2016 +0200
+++ b/hotspot/src/cpu/zero/vm/bytecodeInterpreter_zero.cpp	Mon Apr 25 09:51:00 2016 -0400
@@ -49,6 +49,7 @@
   DO(_locals);
   DO(_constants);
   DO(_method);
+  DO(_mirror);
   DO(_mdx);
   DO(_stack);
   DO(_msg);
@@ -77,6 +78,7 @@
                                                   bool      is_top_frame) {
   istate->set_locals(locals);
   istate->set_method(method);
+  istate->set_mirror(method->method_holder()->java_mirror());
   istate->set_self_link(istate);
   istate->set_prev_link(NULL);
   // thread will be set by a hacky repurposing of frame::patch_pc()
--- a/hotspot/src/cpu/zero/vm/bytecodeInterpreter_zero.hpp	Mon Apr 25 11:36:14 2016 +0200
+++ b/hotspot/src/cpu/zero/vm/bytecodeInterpreter_zero.hpp	Mon Apr 25 09:51:00 2016 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
  * Copyright 2007, 2008, 2011 Red Hat, Inc.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -44,6 +44,9 @@
   inline void set_method(Method* new_method) {
     _method = new_method;
   }
+  inline void set_mirror(oop new_mirror) {
+    _mirror = new_mirror;
+  }
   inline interpreterState self_link() {
     return _self_link;
   }
--- a/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp	Mon Apr 25 11:36:14 2016 +0200
+++ b/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp	Mon Apr 25 09:51:00 2016 -0400
@@ -755,6 +755,7 @@
 
   istate->set_locals(locals);
   istate->set_method(method);
+  istate->set_mirror(method->method_holder()->java_mirror());
   istate->set_self_link(istate);
   istate->set_prev_link(NULL);
   istate->set_thread(thread);
--- a/hotspot/src/cpu/zero/vm/frame_zero.inline.hpp	Mon Apr 25 11:36:14 2016 +0200
+++ b/hotspot/src/cpu/zero/vm/frame_zero.inline.hpp	Mon Apr 25 09:51:00 2016 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
  * Copyright 2007, 2008, 2009, 2010 Red Hat, Inc.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -115,6 +115,10 @@
   return &(get_interpreterState()->_method);
 }
 
+inline oop* frame::interpreter_frame_mirror_addr() const {
+  return &(get_interpreterState()->_mirror);
+}
+
 inline intptr_t* frame::interpreter_frame_mdp_addr() const {
   return (intptr_t*) &(get_interpreterState()->_mdx);
 }
--- a/hotspot/src/share/vm/gc/g1/g1RootClosures.cpp	Mon Apr 25 11:36:14 2016 +0200
+++ b/hotspot/src/share/vm/gc/g1/g1RootClosures.cpp	Mon Apr 25 09:51:00 2016 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -42,7 +42,6 @@
 
   CLDClosure* weak_clds()             { return &_closures._clds; }
   CLDClosure* strong_clds()           { return &_closures._clds; }
-  CLDClosure* thread_root_clds()      { return NULL; }
   CLDClosure* second_pass_weak_clds() { return NULL; }
 
   CodeBlobClosure* strong_codeblobs()      { return &_closures._codeblobs; }
@@ -89,7 +88,6 @@
 
   // If MarkWeak is G1MarkFromRoot then all CLDs are processed by the weak and strong variants
   // return a NULL closure for the following specialized versions in that case.
-  CLDClosure* thread_root_clds()      { return null_if<G1MarkFromRoot>(&_strong._clds); }
   CLDClosure* second_pass_weak_clds() { return null_if<G1MarkFromRoot>(&_weak._clds); }
 
   CodeBlobClosure* strong_codeblobs()      { return &_strong._codeblobs; }
--- a/hotspot/src/share/vm/gc/g1/g1RootClosures.hpp	Mon Apr 25 11:36:14 2016 +0200
+++ b/hotspot/src/share/vm/gc/g1/g1RootClosures.hpp	Mon Apr 25 09:51:00 2016 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -41,9 +41,6 @@
   virtual CLDClosure* weak_clds() = 0;
   virtual CLDClosure* strong_clds() = 0;
 
-  // Applied to the CLDs reachable from the thread stacks.
-  virtual CLDClosure* thread_root_clds() = 0;
-
   // Applied to code blobs reachable as strong roots.
   virtual CodeBlobClosure* strong_codeblobs() = 0;
 };
--- a/hotspot/src/share/vm/gc/g1/g1RootProcessor.cpp	Mon Apr 25 11:36:14 2016 +0200
+++ b/hotspot/src/share/vm/gc/g1/g1RootProcessor.cpp	Mon Apr 25 09:51:00 2016 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -152,7 +152,6 @@
 
   CLDClosure* weak_clds()        { return NULL; }
   CLDClosure* strong_clds()      { return _clds; }
-  CLDClosure* thread_root_clds() { return _clds; }
 
   CodeBlobClosure* strong_codeblobs() { return _blobs; }
 };
@@ -184,9 +183,6 @@
   // system.
   CLDClosure* weak_clds() { return _clds; }
   CLDClosure* strong_clds() { return _clds; }
-  // We don't want to visit CLDs more than once, so we return NULL for the
-  // thread root CLDs.
-  CLDClosure* thread_root_clds() { return NULL; }
 
   // We don't want to visit code blobs more than once, so we return NULL for the
   // strong case and walk the entire code cache as a separate step.
@@ -211,7 +207,6 @@
 void G1RootProcessor::process_java_roots(G1RootClosures* closures,
                                          G1GCPhaseTimes* phase_times,
                                          uint worker_i) {
-  assert(closures->thread_root_clds() == NULL || closures->weak_clds() == NULL, "There is overlap between those, only one may be set");
   // Iterating over the CLDG and the Threads are done early to allow us to
   // first process the strong CLDs and nmethods and then, after a barrier,
   // let the thread process the weak CLDs and nmethods.
@@ -227,7 +222,6 @@
     bool is_par = n_workers() > 1;
     Threads::possibly_parallel_oops_do(is_par,
                                        closures->strong_oops(),
-                                       closures->thread_root_clds(),
                                        closures->strong_codeblobs());
   }
 }
--- a/hotspot/src/share/vm/gc/parallel/pcTasks.cpp	Mon Apr 25 11:36:14 2016 +0200
+++ b/hotspot/src/share/vm/gc/parallel/pcTasks.cpp	Mon Apr 25 09:51:00 2016 -0400
@@ -58,19 +58,16 @@
     ParCompactionManager::gc_thread_compaction_manager(which);
 
   ParCompactionManager::MarkAndPushClosure mark_and_push_closure(cm);
-  CLDToOopClosure mark_and_push_from_clds(&mark_and_push_closure, true);
   MarkingCodeBlobClosure mark_and_push_in_blobs(&mark_and_push_closure, !CodeBlobToOopClosure::FixRelocations);
 
   if (_java_thread != NULL)
     _java_thread->oops_do(
         &mark_and_push_closure,
-        &mark_and_push_from_clds,
         &mark_and_push_in_blobs);
 
   if (_vm_thread != NULL)
     _vm_thread->oops_do(
         &mark_and_push_closure,
-        &mark_and_push_from_clds,
         &mark_and_push_in_blobs);
 
   // Do the real work
@@ -99,8 +96,7 @@
     {
       ResourceMark rm;
       MarkingCodeBlobClosure each_active_code_blob(&mark_and_push_closure, !CodeBlobToOopClosure::FixRelocations);
-      CLDToOopClosure mark_and_push_from_cld(&mark_and_push_closure);
-      Threads::oops_do(&mark_and_push_closure, &mark_and_push_from_cld, &each_active_code_blob);
+      Threads::oops_do(&mark_and_push_closure, &each_active_code_blob);
     }
     break;
 
--- a/hotspot/src/share/vm/gc/parallel/psMarkSweep.cpp	Mon Apr 25 11:36:14 2016 +0200
+++ b/hotspot/src/share/vm/gc/parallel/psMarkSweep.cpp	Mon Apr 25 09:51:00 2016 -0400
@@ -505,9 +505,8 @@
     ParallelScavengeHeap::ParStrongRootsScope psrs;
     Universe::oops_do(mark_and_push_closure());
     JNIHandles::oops_do(mark_and_push_closure());   // Global (strong) JNI handles
-    CLDToOopClosure mark_and_push_from_cld(mark_and_push_closure());
     MarkingCodeBlobClosure each_active_code_blob(mark_and_push_closure(), !CodeBlobToOopClosure::FixRelocations);
-    Threads::oops_do(mark_and_push_closure(), &mark_and_push_from_cld, &each_active_code_blob);
+    Threads::oops_do(mark_and_push_closure(), &each_active_code_blob);
     ObjectSynchronizer::oops_do(mark_and_push_closure());
     FlatProfiler::oops_do(mark_and_push_closure());
     Management::oops_do(mark_and_push_closure());
@@ -597,8 +596,7 @@
   // General strong roots.
   Universe::oops_do(adjust_pointer_closure());
   JNIHandles::oops_do(adjust_pointer_closure());   // Global (strong) JNI handles
-  CLDToOopClosure adjust_from_cld(adjust_pointer_closure());
-  Threads::oops_do(adjust_pointer_closure(), &adjust_from_cld, NULL);
+  Threads::oops_do(adjust_pointer_closure(), NULL);
   ObjectSynchronizer::oops_do(adjust_pointer_closure());
   FlatProfiler::oops_do(adjust_pointer_closure());
   Management::oops_do(adjust_pointer_closure());
--- a/hotspot/src/share/vm/gc/parallel/psParallelCompact.cpp	Mon Apr 25 11:36:14 2016 +0200
+++ b/hotspot/src/share/vm/gc/parallel/psParallelCompact.cpp	Mon Apr 25 09:51:00 2016 -0400
@@ -2148,8 +2148,7 @@
   // General strong roots.
   Universe::oops_do(&oop_closure);
   JNIHandles::oops_do(&oop_closure);   // Global (strong) JNI handles
-  CLDToOopClosure adjust_from_cld(&oop_closure);
-  Threads::oops_do(&oop_closure, &adjust_from_cld, NULL);
+  Threads::oops_do(&oop_closure, NULL);
   ObjectSynchronizer::oops_do(&oop_closure);
   FlatProfiler::oops_do(&oop_closure);
   Management::oops_do(&oop_closure);
--- a/hotspot/src/share/vm/gc/parallel/psTasks.cpp	Mon Apr 25 11:36:14 2016 +0200
+++ b/hotspot/src/share/vm/gc/parallel/psTasks.cpp	Mon Apr 25 09:51:00 2016 -0400
@@ -65,8 +65,7 @@
     case threads:
     {
       ResourceMark rm;
-      CLDClosure* cld_closure = NULL; // Not needed. All CLDs are already visited.
-      Threads::oops_do(&roots_closure, cld_closure, NULL);
+      Threads::oops_do(&roots_closure, NULL);
     }
     break;
 
@@ -122,14 +121,13 @@
 
   PSPromotionManager* pm = PSPromotionManager::gc_thread_promotion_manager(which);
   PSScavengeRootsClosure roots_closure(pm);
-  CLDClosure* roots_from_clds = NULL;  // Not needed. All CLDs are already visited.
   MarkingCodeBlobClosure roots_in_blobs(&roots_closure, CodeBlobToOopClosure::FixRelocations);
 
   if (_java_thread != NULL)
-    _java_thread->oops_do(&roots_closure, roots_from_clds, &roots_in_blobs);
+    _java_thread->oops_do(&roots_closure, &roots_in_blobs);
 
   if (_vm_thread != NULL)
-    _vm_thread->oops_do(&roots_closure, roots_from_clds, &roots_in_blobs);
+    _vm_thread->oops_do(&roots_closure, &roots_in_blobs);
 
   // Do the real work
   pm->drain_stacks(false);
--- a/hotspot/src/share/vm/gc/shared/genCollectedHeap.cpp	Mon Apr 25 11:36:14 2016 +0200
+++ b/hotspot/src/share/vm/gc/shared/genCollectedHeap.cpp	Mon Apr 25 09:51:00 2016 -0400
@@ -582,14 +582,11 @@
     ClassLoaderDataGraph::roots_cld_do(strong_cld_closure, weak_cld_closure);
   }
 
-  // Some CLDs contained in the thread frames should be considered strong.
-  // Don't process them if they will be processed during the ClassLoaderDataGraph phase.
-  CLDClosure* roots_from_clds_p = (strong_cld_closure != weak_cld_closure) ? strong_cld_closure : NULL;
   // Only process code roots from thread stacks if we aren't visiting the entire CodeCache anyway
   CodeBlobToOopClosure* roots_from_code_p = (so & SO_AllCodeCache) ? NULL : code_roots;
 
   bool is_par = scope->n_threads() > 1;
-  Threads::possibly_parallel_oops_do(is_par, strong_roots, roots_from_clds_p, roots_from_code_p);
+  Threads::possibly_parallel_oops_do(is_par, strong_roots, roots_from_code_p);
 
   if (!_process_strong_tasks->is_task_claimed(GCH_PS_Universe_oops_do)) {
     Universe::oops_do(strong_roots);
--- a/hotspot/src/share/vm/interpreter/bytecodeInterpreter.hpp	Mon Apr 25 11:36:14 2016 +0200
+++ b/hotspot/src/share/vm/interpreter/bytecodeInterpreter.hpp	Mon Apr 25 09:51:00 2016 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 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
@@ -110,6 +110,7 @@
     intptr_t*             _locals;        // local variable pointer
     ConstantPoolCache*    _constants;     // constant pool cache
     Method*               _method;        // method being executed
+    oop                   _mirror;        // mirror to klass containing method
     DataLayout*           _mdx;           // compiler profiling data for current bytecode
     intptr_t*             _stack;         // expression stack
     messages              _msg;           // frame manager <-> interpreter message
--- a/hotspot/src/share/vm/runtime/deoptimization.cpp	Mon Apr 25 11:36:14 2016 +0200
+++ b/hotspot/src/share/vm/runtime/deoptimization.cpp	Mon Apr 25 09:51:00 2016 -0400
@@ -762,7 +762,7 @@
         guarantee(false, "wrong number of expression stack elements during deopt");
       }
       VerifyOopClosure verify;
-      iframe->oops_interpreted_do(&verify, NULL, &rm, false);
+      iframe->oops_interpreted_do(&verify, &rm, false);
       callee_size_of_parameters = mh->size_of_parameters();
       callee_max_locals = mh->max_locals();
       is_top_frame = false;
--- a/hotspot/src/share/vm/runtime/frame.cpp	Mon Apr 25 11:36:14 2016 +0200
+++ b/hotspot/src/share/vm/runtime/frame.cpp	Mon Apr 25 09:51:00 2016 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -396,6 +396,11 @@
   *interpreter_frame_method_addr() = method;
 }
 
+void frame::interpreter_frame_set_mirror(oop mirror) {
+  assert(is_interpreted_frame(), "interpreted frame expected");
+  *interpreter_frame_mirror_addr() = mirror;
+}
+
 jint frame::interpreter_frame_bci() const {
   assert(is_interpreted_frame(), "interpreted frame expected");
   address bcp = interpreter_frame_bcp();
@@ -852,8 +857,7 @@
 }
 
 
-void frame::oops_interpreted_do(OopClosure* f, CLDClosure* cld_f,
-    const RegisterMap* map, bool query_oop_map_cache) {
+void frame::oops_interpreted_do(OopClosure* f, const RegisterMap* map, bool query_oop_map_cache) {
   assert(is_interpreted_frame(), "Not an interpreted frame");
   assert(map != NULL, "map must be set");
   Thread *thread = Thread::current();
@@ -879,20 +883,15 @@
     current->oops_do(f);
   }
 
-  // process fixed part
-  if (cld_f != NULL) {
-    // The method pointer in the frame might be the only path to the method's
-    // klass, and the klass needs to be kept alive while executing. The GCs
-    // don't trace through method pointers, so typically in similar situations
-    // the mirror or the class loader of the klass are installed as a GC root.
-    // To minimize the overhead of doing that here, we ask the GC to pass down a
-    // closure that knows how to keep klasses alive given a ClassLoaderData.
-    cld_f->do_cld(m->method_holder()->class_loader_data());
+  if (m->is_native()) {
+    f->do_oop(interpreter_frame_temp_oop_addr());
   }
 
-  if (m->is_native() PPC32_ONLY(&& m->is_static())) {
-    f->do_oop(interpreter_frame_temp_oop_addr());
-  }
+  // The method pointer in the frame might be the only path to the method's
+  // klass, and the klass needs to be kept alive while executing. The GCs
+  // don't trace through method pointers, so the mirror of the method's klass
+  // is installed as a GC root.
+  f->do_oop(interpreter_frame_mirror_addr());
 
   int max_locals = m->is_native() ? m->size_of_parameters() : m->max_locals();
 
@@ -1093,7 +1092,7 @@
 }
 
 
-void frame::oops_do_internal(OopClosure* f, CLDClosure* cld_f, CodeBlobClosure* cf, RegisterMap* map, bool use_interpreter_oop_map_cache) {
+void frame::oops_do_internal(OopClosure* f, CodeBlobClosure* cf, RegisterMap* map, bool use_interpreter_oop_map_cache) {
 #ifndef PRODUCT
   // simulate GC crash here to dump java thread in error report
   if (CrashGCForDumpingJavaThread) {
@@ -1102,7 +1101,7 @@
   }
 #endif
   if (is_interpreted_frame()) {
-    oops_interpreted_do(f, cld_f, map, use_interpreter_oop_map_cache);
+    oops_interpreted_do(f, map, use_interpreter_oop_map_cache);
   } else if (is_entry_frame()) {
     oops_entry_do(f, map);
   } else if (CodeCache::contains(pc())) {
@@ -1147,7 +1146,7 @@
 #if defined(COMPILER2) || INCLUDE_JVMCI
   assert(DerivedPointerTable::is_empty(), "must be empty before verify");
 #endif
-  oops_do_internal(&VerifyOopClosure::verify_oop, NULL, NULL, (RegisterMap*)map, false);
+  oops_do_internal(&VerifyOopClosure::verify_oop, NULL, (RegisterMap*)map, false);
 }
 
 
--- a/hotspot/src/share/vm/runtime/frame.hpp	Mon Apr 25 11:36:14 2016 +0200
+++ b/hotspot/src/share/vm/runtime/frame.hpp	Mon Apr 25 09:51:00 2016 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -320,6 +320,9 @@
   void interpreter_frame_set_method(Method* method);
   Method** interpreter_frame_method_addr() const;
   ConstantPoolCache** interpreter_frame_cache_addr() const;
+  oop* interpreter_frame_mirror_addr() const;
+
+  void interpreter_frame_set_mirror(oop mirror);
 
  public:
   // Entry frames
@@ -386,19 +389,19 @@
 
   // Oops-do's
   void oops_compiled_arguments_do(Symbol* signature, bool has_receiver, bool has_appendix, const RegisterMap* reg_map, OopClosure* f);
-  void oops_interpreted_do(OopClosure* f, CLDClosure* cld_f, const RegisterMap* map, bool query_oop_map_cache = true);
+  void oops_interpreted_do(OopClosure* f, const RegisterMap* map, bool query_oop_map_cache = true);
 
  private:
   void oops_interpreted_arguments_do(Symbol* signature, bool has_receiver, OopClosure* f);
 
   // Iteration of oops
-  void oops_do_internal(OopClosure* f, CLDClosure* cld_f, CodeBlobClosure* cf, RegisterMap* map, bool use_interpreter_oop_map_cache);
+  void oops_do_internal(OopClosure* f, CodeBlobClosure* cf, RegisterMap* map, bool use_interpreter_oop_map_cache);
   void oops_entry_do(OopClosure* f, const RegisterMap* map);
   void oops_code_blob_do(OopClosure* f, CodeBlobClosure* cf, const RegisterMap* map);
   int adjust_offset(Method* method, int index); // helper for above fn
  public:
   // Memory management
-  void oops_do(OopClosure* f, CLDClosure* cld_f, CodeBlobClosure* cf, RegisterMap* map) { oops_do_internal(f, cld_f, cf, map, true); }
+  void oops_do(OopClosure* f, CodeBlobClosure* cf, RegisterMap* map) { oops_do_internal(f, cf, map, true); }
   void nmethods_do(CodeBlobClosure* cf);
 
   // RedefineClasses support for finding live interpreted methods on the stack
--- a/hotspot/src/share/vm/runtime/thread.cpp	Mon Apr 25 11:36:14 2016 +0200
+++ b/hotspot/src/share/vm/runtime/thread.cpp	Mon Apr 25 09:51:00 2016 -0400
@@ -785,7 +785,7 @@
   return false;
 }
 
-void Thread::oops_do(OopClosure* f, CLDClosure* cld_f, CodeBlobClosure* cf) {
+void Thread::oops_do(OopClosure* f, CodeBlobClosure* cf) {
   active_handles()->oops_do(f);
   // Do oop for ThreadShadow
   f->do_oop((oop*)&_pending_exception);
@@ -2758,7 +2758,7 @@
   }
 };
 
-void JavaThread::oops_do(OopClosure* f, CLDClosure* cld_f, CodeBlobClosure* cf) {
+void JavaThread::oops_do(OopClosure* f, CodeBlobClosure* cf) {
   // Verify that the deferred card marks have been flushed.
   assert(deferred_card_mark().is_empty(), "Should be empty during GC");
 
@@ -2766,7 +2766,7 @@
   // since there may be more than one thread using each ThreadProfiler.
 
   // Traverse the GCHandles
-  Thread::oops_do(f, cld_f, cf);
+  Thread::oops_do(f, cf);
 
   JVMCI_ONLY(f->do_oop((oop*)&_pending_failed_speculation);)
 
@@ -2796,7 +2796,7 @@
 
     // Traverse the execution stack
     for (StackFrameStream fst(this); !fst.is_done(); fst.next()) {
-      fst.current()->oops_do(f, cld_f, cf, fst.register_map());
+      fst.current()->oops_do(f, cf, fst.register_map());
     }
   }
 
@@ -2946,7 +2946,7 @@
 
 void JavaThread::verify() {
   // Verify oops in the thread.
-  oops_do(&VerifyOopClosure::verify_oop, NULL, NULL);
+  oops_do(&VerifyOopClosure::verify_oop, NULL);
 
   // Verify the stack frames.
   frames_do(frame_verify);
@@ -3186,7 +3186,7 @@
 static void oops_print(frame* f, const RegisterMap *map) {
   PrintAndVerifyOopClosure print;
   f->print_value();
-  f->oops_do(&print, NULL, NULL, (RegisterMap*)map);
+  f->oops_do(&print, NULL, (RegisterMap*)map);
 }
 
 // Print our all the locations that contain oops and whether they are
@@ -3303,8 +3303,8 @@
   _scanned_nmethod = NULL;
 }
 
-void CodeCacheSweeperThread::oops_do(OopClosure* f, CLDClosure* cld_f, CodeBlobClosure* cf) {
-  JavaThread::oops_do(f, cld_f, cf);
+void CodeCacheSweeperThread::oops_do(OopClosure* f, CodeBlobClosure* cf) {
+  JavaThread::oops_do(f, cf);
   if (_scanned_nmethod != NULL && cf != NULL) {
     // Safepoints can occur when the sweeper is scanning an nmethod so
     // process it here to make sure it isn't unloaded in the middle of
@@ -4291,11 +4291,11 @@
 // uses the Threads_lock to guarantee this property. It also makes sure that
 // all threads gets blocked when exiting or starting).
 
-void Threads::oops_do(OopClosure* f, CLDClosure* cld_f, CodeBlobClosure* cf) {
+void Threads::oops_do(OopClosure* f, CodeBlobClosure* cf) {
   ALL_JAVA_THREADS(p) {
-    p->oops_do(f, cld_f, cf);
-  }
-  VMThread::vm_thread()->oops_do(f, cld_f, cf);
+    p->oops_do(f, cf);
+  }
+  VMThread::vm_thread()->oops_do(f, cf);
 }
 
 void Threads::change_thread_claim_parity() {
@@ -4318,16 +4318,16 @@
 }
 #endif // ASSERT
 
-void Threads::possibly_parallel_oops_do(bool is_par, OopClosure* f, CLDClosure* cld_f, CodeBlobClosure* cf) {
+void Threads::possibly_parallel_oops_do(bool is_par, OopClosure* f, CodeBlobClosure* cf) {
   int cp = Threads::thread_claim_parity();
   ALL_JAVA_THREADS(p) {
     if (p->claim_oops_do(is_par, cp)) {
-      p->oops_do(f, cld_f, cf);
+      p->oops_do(f, cf);
     }
   }
   VMThread* vmt = VMThread::vm_thread();
   if (vmt->claim_oops_do(is_par, cp)) {
-    vmt->oops_do(f, cld_f, cf);
+    vmt->oops_do(f, cf);
   }
 }
 
--- a/hotspot/src/share/vm/runtime/thread.hpp	Mon Apr 25 11:36:14 2016 +0200
+++ b/hotspot/src/share/vm/runtime/thread.hpp	Mon Apr 25 09:51:00 2016 -0400
@@ -482,10 +482,9 @@
 
   // GC support
   // Apply "f->do_oop" to all root oops in "this".
-  // Apply "cld_f->do_cld" to CLDs that are otherwise not kept alive.
   //   Used by JavaThread::oops_do.
   // Apply "cf->do_code_blob" (if !NULL) to all code blobs active in frames
-  virtual void oops_do(OopClosure* f, CLDClosure* cld_f, CodeBlobClosure* cf);
+  virtual void oops_do(OopClosure* f, CodeBlobClosure* cf);
 
   // Handles the parallel case for the method below.
  private:
@@ -1642,7 +1641,7 @@
   void frames_do(void f(frame*, const RegisterMap*));
 
   // Memory operations
-  void oops_do(OopClosure* f, CLDClosure* cld_f, CodeBlobClosure* cf);
+  void oops_do(OopClosure* f, CodeBlobClosure* cf);
 
   // Sweeper operations
   virtual void nmethods_do(CodeBlobClosure* cf);
@@ -1995,7 +1994,7 @@
   bool is_Code_cache_sweeper_thread() const { return true; }
 
   // Prevent GC from unloading _scanned_nmethod
-  void oops_do(OopClosure* f, CLDClosure* cld_f, CodeBlobClosure* cf);
+  void oops_do(OopClosure* f, CodeBlobClosure* cf);
   void nmethods_do(CodeBlobClosure* cf);
 };
 
@@ -2122,9 +2121,9 @@
 
   // Apply "f->do_oop" to all root oops in all threads.
   // This version may only be called by sequential code.
-  static void oops_do(OopClosure* f, CLDClosure* cld_f, CodeBlobClosure* cf);
+  static void oops_do(OopClosure* f, CodeBlobClosure* cf);
   // This version may be called by sequential or parallel code.
-  static void possibly_parallel_oops_do(bool is_par, OopClosure* f, CLDClosure* cld_f, CodeBlobClosure* cf);
+  static void possibly_parallel_oops_do(bool is_par, OopClosure* f, CodeBlobClosure* cf);
   // This creates a list of GCTasks, one per thread.
   static void create_thread_roots_tasks(GCTaskQueue* q);
   // This creates a list of GCTasks, one per thread, for marking objects.
--- a/hotspot/src/share/vm/runtime/vmThread.cpp	Mon Apr 25 11:36:14 2016 +0200
+++ b/hotspot/src/share/vm/runtime/vmThread.cpp	Mon Apr 25 09:51:00 2016 -0400
@@ -655,8 +655,8 @@
 }
 
 
-void VMThread::oops_do(OopClosure* f, CLDClosure* cld_f, CodeBlobClosure* cf) {
-  Thread::oops_do(f, cld_f, cf);
+void VMThread::oops_do(OopClosure* f, CodeBlobClosure* cf) {
+  Thread::oops_do(f, cf);
   _vm_queue->oops_do(f);
 }
 
@@ -688,5 +688,5 @@
 #endif
 
 void VMThread::verify() {
-  oops_do(&VerifyOopClosure::verify_oop, NULL, NULL);
+  oops_do(&VerifyOopClosure::verify_oop, NULL);
 }
--- a/hotspot/src/share/vm/runtime/vmThread.hpp	Mon Apr 25 11:36:14 2016 +0200
+++ b/hotspot/src/share/vm/runtime/vmThread.hpp	Mon Apr 25 09:51:00 2016 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -126,7 +126,7 @@
   static VMThread* vm_thread()                    { return _vm_thread; }
 
   // GC support
-  void oops_do(OopClosure* f, CLDClosure* cld_f, CodeBlobClosure* cf);
+  void oops_do(OopClosure* f, CodeBlobClosure* cf);
 
   void verify();
 
--- a/hotspot/test/TEST.groups	Mon Apr 25 11:36:14 2016 +0200
+++ b/hotspot/test/TEST.groups	Mon Apr 25 09:51:00 2016 -0400
@@ -353,7 +353,7 @@
   runtime/ \
  -runtime/ErrorHandling/ErrorHandler.java \
  -runtime/RedefineObject/TestRedefineObject.java \
- -runtime/8003720/Test8003720.java \
+ -runtime/MirrorFrame/Test8003720.java \
  -runtime/Metaspace/FragmentMetaspace.java \
  -runtime/Metaspace/FragmentMetaspaceSimple.java \
  -runtime/Thread/TestThreadDumpMonitorContention.java \
--- a/hotspot/test/runtime/8003720/Asmator.java	Mon Apr 25 11:36:14 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,56 +0,0 @@
-/*
- * Copyright (c) 2012, 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.
- *
- */
-
-import jdk.internal.org.objectweb.asm.*;
-
-class Asmator {
-    static byte[] fixup(byte[] buf) throws java.io.IOException {
-        ClassReader cr = new ClassReader(buf);
-        ClassWriter cw = new ClassWriter(0);
-        ClassVisitor cv = new ClassVisitor(Opcodes.ASM4, cw) {
-            public MethodVisitor visitMethod(
-                final int access,
-                final String name,
-                final String desc,
-                final String signature,
-                final String[] exceptions)
-            {
-                MethodVisitor mv = super.visitMethod(access,
-                        name,
-                        desc,
-                        signature,
-                        exceptions);
-                if (mv == null)  return null;
-                if (name.equals("callme")) {
-                    // make receiver go dead!
-                    mv.visitInsn(Opcodes.ACONST_NULL);
-                    mv.visitVarInsn(Opcodes.ASTORE, 0);
-                }
-                return mv;
-            }
-        };
-        cr.accept(cv, 0);
-        return cw.toByteArray();
-    }
-}
--- a/hotspot/test/runtime/8003720/Test8003720.java	Mon Apr 25 11:36:14 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,73 +0,0 @@
-/*
- * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-/*
- * @test
- * @bug 8003720
- * @summary Method in interpreter stack frame can be deallocated
- * @modules java.base/jdk.internal.org.objectweb.asm
- *          java.base/jdk.internal.misc
- * @compile -XDignore.symbol.file Victim.java
- * @run main/othervm -Xverify:all -Xint Test8003720
- */
-
-// Attempts to make the JVM unload a class while still executing one of its methods.
-public class Test8003720 {
-    final static String VICTIM_CLASS_NAME = "Victim";
-    final static boolean QUIET = true;
-    final static long DURATION = 30000;
-
-    public interface CallMe { void callme(); }
-
-    public static void main(String... av) throws Throwable {
-        newVictimClassLoader();
-        System.gc();
-
-        newVictimClass();
-        System.gc();
-
-        newVictimInstance();
-        System.gc();
-
-        ((CallMe)newVictimInstance()).callme();
-    }
-
-    public static Object newVictimInstance() throws Throwable {
-        return newVictimClass().newInstance();
-    }
-
-    public static Class<?> newVictimClass() throws Throwable {
-        return Class.forName(VICTIM_CLASS_NAME, true, new VictimClassLoader());
-    }
-
-    public static ClassLoader newVictimClassLoader() throws Throwable {
-        return new VictimClassLoader();
-    }
-
-    public static void println(String line) {
-        if (!QUIET) {
-            System.out.println(line);
-        }
-    }
-}
--- a/hotspot/test/runtime/8003720/Victim.java	Mon Apr 25 11:36:14 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,50 +0,0 @@
-/*
- * Copyright (c) 2012, 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.
- *
- */
-
-public class Victim implements Test8003720.CallMe {
-    public void callme() {
-        // note: Victim.this is dead here
-        Test8003720.println("executing in loader=" + Victim.class.getClassLoader());
-
-        long now = System.currentTimeMillis();
-
-        while ((System.currentTimeMillis() - now) < Test8003720.DURATION) {
-            long count = VictimClassLoader.counter++;
-            if (count %  1000000 == 0)  System.gc();
-            if (count % 16180000 == 0)  blurb();
-            new Object[1].clone();
-        }
-    }
-    static void blurb() {
-        Test8003720.println("count=" + VictimClassLoader.counter);
-    }
-    static {
-        blather();
-    }
-    static void blather() {
-        new java.util.ArrayList<Object>(1000000);
-        Class<Victim> c = Victim.class;
-        Test8003720.println("initializing " + c + "#" + System.identityHashCode(c) + " in " + c.getClassLoader());
-    }
-}
--- a/hotspot/test/runtime/8003720/VictimClassLoader.java	Mon Apr 25 11:36:14 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,88 +0,0 @@
-/*
- * Copyright (c) 2012, 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.
- *
- */
-
-public class VictimClassLoader extends ClassLoader {
-    public static long counter = 0;
-
-    private int which = (int) ++counter;
-
-    protected VictimClassLoader() {
-        super(VictimClassLoader.class.getClassLoader());
-    }
-
-    protected Class loadClass(String name, boolean resolve) throws ClassNotFoundException {
-        Class c;
-        if (!name.endsWith("Victim")) {
-            c = super.loadClass(name, resolve);
-            return c;
-        }
-
-        c = findLoadedClass(name);
-        if (c != null) {
-            return c;
-        }
-
-        byte[] buf = readClassFile(name);
-        c = defineClass(name, buf, 0, buf.length);
-        resolveClass(c);
-
-        if (c.getClassLoader() != this) {
-            throw new AssertionError();
-        }
-
-        Test8003720.println("loaded " + c + "#" + System.identityHashCode(c) + " in " + c.getClassLoader());
-        return c;
-    }
-
-    static byte[] readClassFile(String name) {
-        try {
-            String rname = name.substring(name.lastIndexOf('.') + 1) + ".class";
-            java.net.URL url = VictimClassLoader.class.getResource(rname);
-            Test8003720.println("found " + rname + " = " + url);
-
-            java.net.URLConnection connection = url.openConnection();
-            int contentLength = connection.getContentLength();
-            byte[] buf = readFully(connection.getInputStream(), contentLength);
-
-            return Asmator.fixup(buf);
-        } catch (java.io.IOException ex) {
-            throw new Error(ex);
-        }
-    }
-
-    static byte[] readFully(java.io.InputStream in, int len) throws java.io.IOException {
-        byte[] b = in.readAllBytes();
-        if (len != -1 && b.length != len)
-            throw new java.io.IOException("Expected:" + len + ", actual:" + b.length);
-        return b;
-    }
-
-    public void finalize() {
-        Test8003720.println("Goodbye from " + this);
-    }
-
-    public String toString() {
-        return "VictimClassLoader#" + which;
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/MirrorFrame/Asmator.java	Mon Apr 25 09:51:00 2016 -0400
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2012, 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.
+ *
+ */
+
+import jdk.internal.org.objectweb.asm.*;
+
+class Asmator {
+    static byte[] fixup(byte[] buf) throws java.io.IOException {
+        ClassReader cr = new ClassReader(buf);
+        ClassWriter cw = new ClassWriter(0);
+        ClassVisitor cv = new ClassVisitor(Opcodes.ASM4, cw) {
+            public MethodVisitor visitMethod(
+                final int access,
+                final String name,
+                final String desc,
+                final String signature,
+                final String[] exceptions)
+            {
+                MethodVisitor mv = super.visitMethod(access,
+                        name,
+                        desc,
+                        signature,
+                        exceptions);
+                if (mv == null)  return null;
+                if (name.equals("callme")) {
+                    // make receiver go dead!
+                    mv.visitInsn(Opcodes.ACONST_NULL);
+                    mv.visitVarInsn(Opcodes.ASTORE, 0);
+                }
+                return mv;
+            }
+        };
+        cr.accept(cv, 0);
+        return cw.toByteArray();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/MirrorFrame/Test8003720.java	Mon Apr 25 09:51:00 2016 -0400
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/*
+ * @test
+ * @bug 8003720
+ * @summary Method in interpreter stack frame can be deallocated
+ * @modules java.base/jdk.internal.org.objectweb.asm
+ *          java.base/jdk.internal.misc
+ * @compile -XDignore.symbol.file Victim.java
+ * @run main/othervm -Xverify:all -Xint Test8003720
+ */
+
+// Attempts to make the JVM unload a class while still executing one of its methods.
+public class Test8003720 {
+    final static String VICTIM_CLASS_NAME = "Victim";
+    final static boolean QUIET = true;
+    final static long DURATION = 30000;
+
+    public interface CallMe { void callme(); }
+
+    public static void main(String... av) throws Throwable {
+        newVictimClassLoader();
+        System.gc();
+
+        newVictimClass();
+        System.gc();
+
+        newVictimInstance();
+        System.gc();
+
+        ((CallMe)newVictimInstance()).callme();
+    }
+
+    public static Object newVictimInstance() throws Throwable {
+        return newVictimClass().newInstance();
+    }
+
+    public static Class<?> newVictimClass() throws Throwable {
+        return Class.forName(VICTIM_CLASS_NAME, true, new VictimClassLoader());
+    }
+
+    public static ClassLoader newVictimClassLoader() throws Throwable {
+        return new VictimClassLoader();
+    }
+
+    public static void println(String line) {
+        if (!QUIET) {
+            System.out.println(line);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/MirrorFrame/Victim.java	Mon Apr 25 09:51:00 2016 -0400
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2012, 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.
+ *
+ */
+
+public class Victim implements Test8003720.CallMe {
+    public void callme() {
+        // note: Victim.this is dead here
+        Test8003720.println("executing in loader=" + Victim.class.getClassLoader());
+
+        long now = System.currentTimeMillis();
+
+        while ((System.currentTimeMillis() - now) < Test8003720.DURATION) {
+            long count = VictimClassLoader.counter++;
+            if (count %  1000000 == 0)  System.gc();
+            if (count % 16180000 == 0)  blurb();
+            new Object[1].clone();
+        }
+    }
+    static void blurb() {
+        Test8003720.println("count=" + VictimClassLoader.counter);
+    }
+    static {
+        blather();
+    }
+    static void blather() {
+        new java.util.ArrayList<Object>(1000000);
+        Class<Victim> c = Victim.class;
+        Test8003720.println("initializing " + c + "#" + System.identityHashCode(c) + " in " + c.getClassLoader());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/MirrorFrame/VictimClassLoader.java	Mon Apr 25 09:51:00 2016 -0400
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2012, 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.
+ *
+ */
+
+public class VictimClassLoader extends ClassLoader {
+    public static long counter = 0;
+
+    private int which = (int) ++counter;
+
+    protected VictimClassLoader() {
+        super(VictimClassLoader.class.getClassLoader());
+    }
+
+    protected Class loadClass(String name, boolean resolve) throws ClassNotFoundException {
+        Class c;
+        if (!name.endsWith("Victim")) {
+            c = super.loadClass(name, resolve);
+            return c;
+        }
+
+        c = findLoadedClass(name);
+        if (c != null) {
+            return c;
+        }
+
+        byte[] buf = readClassFile(name);
+        c = defineClass(name, buf, 0, buf.length);
+        resolveClass(c);
+
+        if (c.getClassLoader() != this) {
+            throw new AssertionError();
+        }
+
+        Test8003720.println("loaded " + c + "#" + System.identityHashCode(c) + " in " + c.getClassLoader());
+        return c;
+    }
+
+    static byte[] readClassFile(String name) {
+        try {
+            String rname = name.substring(name.lastIndexOf('.') + 1) + ".class";
+            java.net.URL url = VictimClassLoader.class.getResource(rname);
+            Test8003720.println("found " + rname + " = " + url);
+
+            java.net.URLConnection connection = url.openConnection();
+            int contentLength = connection.getContentLength();
+            byte[] buf = readFully(connection.getInputStream(), contentLength);
+
+            return Asmator.fixup(buf);
+        } catch (java.io.IOException ex) {
+            throw new Error(ex);
+        }
+    }
+
+    static byte[] readFully(java.io.InputStream in, int len) throws java.io.IOException {
+        byte[] b = in.readAllBytes();
+        if (len != -1 && b.length != len)
+            throw new java.io.IOException("Expected:" + len + ", actual:" + b.length);
+        return b;
+    }
+
+    public void finalize() {
+        Test8003720.println("Goodbye from " + this);
+    }
+
+    public String toString() {
+        return "VictimClassLoader#" + which;
+    }
+}