changeset 11853:c3f20f5f5876

Merge
author iveresov
date Fri, 19 Aug 2016 14:33:52 -0700
parents b57963fcd4f3 f932a58df902
children 63d56d2b3435 7c52bc363c21
files test/compiler/profiling/spectrapredefineclass/Launcher.java test/compiler/profiling/spectrapredefineclass_classloaders/Launcher.java test/compiler/startup/StartupOutput.java
diffstat 41 files changed, 215 insertions(+), 155 deletions(-) [+]
line wrap: on
line diff
--- a/src/cpu/aarch64/vm/aarch64.ad	Fri Aug 19 20:38:30 2016 +0200
+++ b/src/cpu/aarch64/vm/aarch64.ad	Fri Aug 19 14:33:52 2016 -0700
@@ -4680,7 +4680,7 @@
       Label retaddr;
       __ adr(rscratch2, retaddr);
       __ lea(rscratch1, RuntimeAddress(entry));
-      // Leave a breadcrumb for JavaThread::pd_last_frame().
+      // Leave a breadcrumb for JavaFrameAnchor::capture_last_Java_pc()
       __ stp(zr, rscratch2, Address(__ pre(sp, -2 * wordSize)));
       __ blrt(rscratch1, gpcnt, fpcnt, rtype);
       __ bind(retaddr);
--- a/src/cpu/aarch64/vm/c1_Runtime1_aarch64.cpp	Fri Aug 19 20:38:30 2016 +0200
+++ b/src/cpu/aarch64/vm/c1_Runtime1_aarch64.cpp	Fri Aug 19 14:33:52 2016 -0700
@@ -78,7 +78,7 @@
   }
   pop(r0, sp);
 #endif
-  reset_last_Java_frame(true, true);
+  reset_last_Java_frame(true);
   maybe_isb();
 
   // check for pending exceptions
@@ -547,7 +547,7 @@
     __ bind(L);
   }
 #endif
-  __ reset_last_Java_frame(true, false);
+  __ reset_last_Java_frame(true);
   __ maybe_isb();
 
   // check for pending exceptions
--- a/src/cpu/aarch64/vm/frame_aarch64.cpp	Fri Aug 19 20:38:30 2016 +0200
+++ b/src/cpu/aarch64/vm/frame_aarch64.cpp	Fri Aug 19 14:33:52 2016 -0700
@@ -336,13 +336,16 @@
   JavaFrameAnchor* jfa = entry_frame_call_wrapper()->anchor();
   assert(!entry_frame_is_first(), "next Java fp must be non zero");
   assert(jfa->last_Java_sp() > sp(), "must be above this frame on stack");
+  // Since we are walking the stack now this nested anchor is obviously walkable
+  // even if it wasn't when it was stacked.
+  if (!jfa->walkable()) {
+    // Capture _last_Java_pc (if needed) and mark anchor walkable.
+    jfa->capture_last_Java_pc();
+  }
   map->clear();
   assert(map->include_argument_oops(), "should be set by clear");
-  if (jfa->last_Java_pc() != NULL ) {
-    frame fr(jfa->last_Java_sp(), jfa->last_Java_fp(), jfa->last_Java_pc());
-    return fr;
-  }
-  frame fr(jfa->last_Java_sp(), jfa->last_Java_fp());
+  vmassert(jfa->last_Java_pc() != NULL, "not walkable");
+  frame fr(jfa->last_Java_sp(), jfa->last_Java_fp(), jfa->last_Java_pc());
   return fr;
 }
 
@@ -769,3 +772,21 @@
   init((intptr_t*)sp, (intptr_t*)fp, (address)pc);
 }
 #endif
+
+void JavaFrameAnchor::make_walkable(JavaThread* thread) {
+  // last frame set?
+  if (last_Java_sp() == NULL) return;
+  // already walkable?
+  if (walkable()) return;
+  vmassert(Thread::current() == (Thread*)thread, "not current thread");
+  vmassert(last_Java_sp() != NULL, "not called from Java code?");
+  vmassert(last_Java_pc() == NULL, "already walkable");
+  capture_last_Java_pc();
+  vmassert(walkable(), "something went wrong");
+}
+
+void JavaFrameAnchor::capture_last_Java_pc() {
+  vmassert(_last_Java_sp != NULL, "no last frame set");
+  vmassert(_last_Java_pc == NULL, "already walkable");
+  _last_Java_pc = (address)_last_Java_sp[-1];
+}
--- a/src/cpu/aarch64/vm/interp_masm_aarch64.hpp	Fri Aug 19 20:38:30 2016 +0200
+++ b/src/cpu/aarch64/vm/interp_masm_aarch64.hpp	Fri Aug 19 14:33:52 2016 -0700
@@ -201,7 +201,7 @@
 // #endif
     MacroAssembler::null_check(reg, offset);
 // #ifdef ASSERT
-//     reset_last_Java_frame(true, false);
+//     reset_last_Java_frame(true);
 // #endif
   }
 
--- a/src/cpu/aarch64/vm/javaFrameAnchor_aarch64.hpp	Fri Aug 19 20:38:30 2016 +0200
+++ b/src/cpu/aarch64/vm/javaFrameAnchor_aarch64.hpp	Fri Aug 19 14:33:52 2016 -0700
@@ -64,10 +64,9 @@
     _last_Java_sp = src->_last_Java_sp;
   }
 
-  // Always walkable
-  bool walkable(void) { return true; }
-  // Never any thing to do since we are always walkable and can find address of return addresses
-  void make_walkable(JavaThread* thread) { }
+  bool walkable(void)                            { return _last_Java_sp != NULL && _last_Java_pc != NULL; }
+  void make_walkable(JavaThread* thread);
+  void capture_last_Java_pc(void);
 
   intptr_t* last_Java_sp(void) const             { return _last_Java_sp; }
 
--- a/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp	Fri Aug 19 20:38:30 2016 +0200
+++ b/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp	Fri Aug 19 14:33:52 2016 -0700
@@ -274,19 +274,18 @@
 }
 
 
-void MacroAssembler::reset_last_Java_frame(bool clear_fp,
-                                           bool clear_pc) {
+void MacroAssembler::reset_last_Java_frame(bool clear_fp) {
   // we must set sp to zero to clear frame
   str(zr, Address(rthread, JavaThread::last_Java_sp_offset()));
+
   // must clear fp, so that compiled frames are not confused; it is
   // possible that we need it only for debugging
   if (clear_fp) {
     str(zr, Address(rthread, JavaThread::last_Java_fp_offset()));
   }
 
-  if (clear_pc) {
-    str(zr, Address(rthread, JavaThread::last_Java_pc_offset()));
-  }
+  // Always clear the pc because it could have been set by make_walkable()
+  str(zr, Address(rthread, JavaThread::last_Java_pc_offset()));
 }
 
 // Calls to C land
@@ -632,7 +631,7 @@
 
   // reset last Java frame
   // Only interpreter should have to clear fp
-  reset_last_Java_frame(true, true);
+  reset_last_Java_frame(true);
 
    // C++ interp handles this in the interpreter
   check_and_handle_popframe(java_thread);
@@ -875,7 +874,7 @@
   if (type == bytecode_start) {
     // set_last_Java_frame(esp, rfp, (address)NULL);
     Assembler:: notify(type);
-    // reset_last_Java_frame(true, false);
+    // reset_last_Java_frame(true);
   }
   else
     Assembler:: notify(type);
--- a/src/cpu/aarch64/vm/macroAssembler_aarch64.hpp	Fri Aug 19 20:38:30 2016 +0200
+++ b/src/cpu/aarch64/vm/macroAssembler_aarch64.hpp	Fri Aug 19 14:33:52 2016 -0700
@@ -757,10 +757,10 @@
                            Register last_java_pc,
                            Register scratch);
 
-  void reset_last_Java_frame(Register thread, bool clearfp, bool clear_pc);
+  void reset_last_Java_frame(Register thread);
 
-  // thread in the default location (r15_thread on 64bit)
-  void reset_last_Java_frame(bool clear_fp, bool clear_pc);
+  // thread in the default location (rthread)
+  void reset_last_Java_frame(bool clear_fp);
 
   // Stores
   void store_check(Register obj);                // store check for obj - register is destroyed afterwards
--- a/src/cpu/aarch64/vm/sharedRuntime_aarch64.cpp	Fri Aug 19 20:38:30 2016 +0200
+++ b/src/cpu/aarch64/vm/sharedRuntime_aarch64.cpp	Fri Aug 19 14:33:52 2016 -0700
@@ -2030,7 +2030,7 @@
     __ bind(dtrace_method_exit_done);
   }
 
-  __ reset_last_Java_frame(false, true);
+  __ reset_last_Java_frame(false);
 
   // Unpack oop result
   if (ret_type == T_OBJECT || ret_type == T_ARRAY) {
@@ -2370,7 +2370,7 @@
     __ bind(retaddr);
     oop_maps->add_gc_map( __ pc()-start, map->deep_copy());
 
-    __ reset_last_Java_frame(false, false);
+    __ reset_last_Java_frame(false);
 
     __ b(after_fetch_unroll_info_call);
   } // EnableJVMCI
@@ -2465,7 +2465,7 @@
   // find any register it might need.
   oop_maps->add_gc_map(__ pc() - start, map);
 
-  __ reset_last_Java_frame(false, true);
+  __ reset_last_Java_frame(false);
 
 #if INCLUDE_JVMCI
   if (EnableJVMCI) {
@@ -2606,7 +2606,7 @@
                        new OopMap( frame_size_in_words, 0 ));
 
   // Clear fp AND pc
-  __ reset_last_Java_frame(true, true);
+  __ reset_last_Java_frame(true);
 
   // Collect return values
   __ ldrd(v0, Address(sp, RegisterSaver::v0_offset_in_bytes()));
@@ -2709,7 +2709,7 @@
 
   oop_maps->add_gc_map(__ pc() - start, map);
 
-  __ reset_last_Java_frame(false, true);
+  __ reset_last_Java_frame(false);
 
   // move UnrollBlock* into r4
   __ mov(r4, r0);
@@ -2828,7 +2828,7 @@
   oop_maps->add_gc_map(the_pc - start, new OopMap(SimpleRuntimeFrame::framesize, 0));
 
   // Clear fp AND pc
-  __ reset_last_Java_frame(true, true);
+  __ reset_last_Java_frame(true);
 
   // Pop self-frame.
   __ leave();                 // Epilog
@@ -2906,7 +2906,7 @@
 
   Label noException;
 
-  __ reset_last_Java_frame(false, true);
+  __ reset_last_Java_frame(false);
 
   __ maybe_isb();
   __ membar(Assembler::LoadLoad | Assembler::LoadStore);
@@ -2985,7 +2985,7 @@
   // r0 contains the address we are going to jump to assuming no exception got installed
 
   // clear last_Java_sp
-  __ reset_last_Java_frame(false, true);
+  __ reset_last_Java_frame(false);
   // check for pending exceptions
   Label pending;
   __ ldr(rscratch1, Address(rthread, Thread::pending_exception_offset()));
@@ -3116,7 +3116,7 @@
 
   oop_maps->add_gc_map(the_pc - start, new OopMap(SimpleRuntimeFrame::framesize, 0));
 
-  __ reset_last_Java_frame(false, true);
+  __ reset_last_Java_frame(false);
 
   // Restore callee-saved registers
 
--- a/src/cpu/aarch64/vm/stubGenerator_aarch64.cpp	Fri Aug 19 20:38:30 2016 +0200
+++ b/src/cpu/aarch64/vm/stubGenerator_aarch64.cpp	Fri Aug 19 14:33:52 2016 -0700
@@ -3801,7 +3801,7 @@
 
     oop_maps->add_gc_map(the_pc - start, map);
 
-    __ reset_last_Java_frame(true, true);
+    __ reset_last_Java_frame(true);
     __ maybe_isb();
 
     __ leave();
--- a/src/cpu/aarch64/vm/templateInterpreterGenerator_aarch64.cpp	Fri Aug 19 20:38:30 2016 +0200
+++ b/src/cpu/aarch64/vm/templateInterpreterGenerator_aarch64.cpp	Fri Aug 19 14:33:52 2016 -0700
@@ -1353,7 +1353,7 @@
   __ stlrw(rscratch1, rscratch2);
 
   // reset_last_Java_frame
-  __ reset_last_Java_frame(true, true);
+  __ reset_last_Java_frame(true);
 
   // reset handle block
   __ ldr(t, Address(rthread, JavaThread::active_handles_offset()));
--- a/src/cpu/x86/vm/c1_Runtime1_x86.cpp	Fri Aug 19 20:38:30 2016 +0200
+++ b/src/cpu/x86/vm/c1_Runtime1_x86.cpp	Fri Aug 19 14:33:52 2016 -0700
@@ -98,7 +98,7 @@
   }
   pop(rax);
 #endif
-  reset_last_Java_frame(thread, true, align_stack);
+  reset_last_Java_frame(thread, true);
 
   // discard thread and arguments
   NOT_LP64(addptr(rsp, num_rt_args()*BytesPerWord));
@@ -872,7 +872,7 @@
   }
   __ pop(rax);
 #endif
-  __ reset_last_Java_frame(thread, true, false);
+  __ reset_last_Java_frame(thread, true);
 #ifndef _LP64
   __ pop(rcx); // discard thread arg
   __ pop(rcx); // discard dummy
--- a/src/cpu/x86/vm/frame_x86.cpp	Fri Aug 19 20:38:30 2016 +0200
+++ b/src/cpu/x86/vm/frame_x86.cpp	Fri Aug 19 14:33:52 2016 -0700
@@ -337,13 +337,16 @@
   JavaFrameAnchor* jfa = entry_frame_call_wrapper()->anchor();
   assert(!entry_frame_is_first(), "next Java fp must be non zero");
   assert(jfa->last_Java_sp() > sp(), "must be above this frame on stack");
+  // Since we are walking the stack now this nested anchor is obviously walkable
+  // even if it wasn't when it was stacked.
+  if (!jfa->walkable()) {
+    // Capture _last_Java_pc (if needed) and mark anchor walkable.
+    jfa->capture_last_Java_pc();
+  }
   map->clear();
   assert(map->include_argument_oops(), "should be set by clear");
-  if (jfa->last_Java_pc() != NULL ) {
-    frame fr(jfa->last_Java_sp(), jfa->last_Java_fp(), jfa->last_Java_pc());
-    return fr;
-  }
-  frame fr(jfa->last_Java_sp(), jfa->last_Java_fp());
+  vmassert(jfa->last_Java_pc() != NULL, "not walkable");
+  frame fr(jfa->last_Java_sp(), jfa->last_Java_fp(), jfa->last_Java_pc());
   return fr;
 }
 
@@ -666,3 +669,21 @@
   init((intptr_t*)sp, (intptr_t*)fp, (address)pc);
 }
 #endif
+
+void JavaFrameAnchor::make_walkable(JavaThread* thread) {
+  // last frame set?
+  if (last_Java_sp() == NULL) return;
+  // already walkable?
+  if (walkable()) return;
+  vmassert(Thread::current() == (Thread*)thread, "not current thread");
+  vmassert(last_Java_sp() != NULL, "not called from Java code?");
+  vmassert(last_Java_pc() == NULL, "already walkable");
+  capture_last_Java_pc();
+  vmassert(walkable(), "something went wrong");
+}
+
+void JavaFrameAnchor::capture_last_Java_pc() {
+  vmassert(_last_Java_sp != NULL, "no last frame set");
+  vmassert(_last_Java_pc == NULL, "already walkable");
+  _last_Java_pc = (address)_last_Java_sp[-1];
+}
--- a/src/cpu/x86/vm/frame_x86.inline.hpp	Fri Aug 19 20:38:30 2016 +0200
+++ b/src/cpu/x86/vm/frame_x86.inline.hpp	Fri Aug 19 14:33:52 2016 -0700
@@ -101,6 +101,7 @@
   // call a specialized frame constructor instead of this one.
   // Then we could use the assert below. However this assert is of somewhat dubious
   // value.
+  // UPDATE: this constructor is only used by trace_method_handle_stub() now.
   // assert(_pc != NULL, "no pc?");
 
   _cb = CodeCache::find_blob(_pc);
--- a/src/cpu/x86/vm/javaFrameAnchor_x86.hpp	Fri Aug 19 20:38:30 2016 +0200
+++ b/src/cpu/x86/vm/javaFrameAnchor_x86.hpp	Fri Aug 19 14:33:52 2016 -0700
@@ -62,10 +62,9 @@
     _last_Java_sp = src->_last_Java_sp;
   }
 
-  // Always walkable
-  bool walkable(void) { return true; }
-  // Never any thing to do since we are always walkable and can find address of return addresses
-  void make_walkable(JavaThread* thread) { }
+  bool walkable(void)                            { return _last_Java_sp != NULL && _last_Java_pc != NULL; }
+  void make_walkable(JavaThread* thread);
+  void capture_last_Java_pc(void);
 
   intptr_t* last_Java_sp(void) const             { return _last_Java_sp; }
 
--- a/src/cpu/x86/vm/macroAssembler_x86.cpp	Fri Aug 19 20:38:30 2016 +0200
+++ b/src/cpu/x86/vm/macroAssembler_x86.cpp	Fri Aug 19 14:33:52 2016 -0700
@@ -752,8 +752,7 @@
   }
 }
 
-void MacroAssembler::reset_last_Java_frame(bool clear_fp,
-                                           bool clear_pc) {
+void MacroAssembler::reset_last_Java_frame(bool clear_fp) {
   // we must set sp to zero to clear frame
   movptr(Address(r15_thread, JavaThread::last_Java_sp_offset()), NULL_WORD);
   // must clear fp, so that compiled frames are not confused; it is
@@ -762,9 +761,8 @@
     movptr(Address(r15_thread, JavaThread::last_Java_fp_offset()), NULL_WORD);
   }
 
-  if (clear_pc) {
-    movptr(Address(r15_thread, JavaThread::last_Java_pc_offset()), NULL_WORD);
-  }
+  // Always clear the pc because it could have been set by make_walkable()
+  movptr(Address(r15_thread, JavaThread::last_Java_pc_offset()), NULL_WORD);
 }
 
 void MacroAssembler::set_last_Java_frame(Register last_java_sp,
@@ -2531,7 +2529,7 @@
   }
   // reset last Java frame
   // Only interpreter should have to clear fp
-  reset_last_Java_frame(java_thread, true, false);
+  reset_last_Java_frame(java_thread, true);
 
    // C++ interp handles this in the interpreter
   check_and_handle_popframe(java_thread);
@@ -3642,8 +3640,7 @@
   pusha();
 }
 
-void MacroAssembler::reset_last_Java_frame(Register java_thread, bool clear_fp, bool clear_pc) {
-  // determine java_thread register
+void MacroAssembler::reset_last_Java_frame(Register java_thread, bool clear_fp) { // determine java_thread register
   if (!java_thread->is_valid()) {
     java_thread = rdi;
     get_thread(java_thread);
@@ -3654,8 +3651,8 @@
     movptr(Address(java_thread, JavaThread::last_Java_fp_offset()), NULL_WORD);
   }
 
-  if (clear_pc)
-    movptr(Address(java_thread, JavaThread::last_Java_pc_offset()), NULL_WORD);
+  // Always clear the pc because it could have been set by make_walkable()
+  movptr(Address(java_thread, JavaThread::last_Java_pc_offset()), NULL_WORD);
 
 }
 
--- a/src/cpu/x86/vm/macroAssembler_x86.hpp	Fri Aug 19 20:38:30 2016 +0200
+++ b/src/cpu/x86/vm/macroAssembler_x86.hpp	Fri Aug 19 14:33:52 2016 -0700
@@ -288,10 +288,10 @@
                            Register last_java_fp,
                            address last_java_pc);
 
-  void reset_last_Java_frame(Register thread, bool clear_fp, bool clear_pc);
+  void reset_last_Java_frame(Register thread, bool clear_fp);
 
   // thread in the default location (r15_thread on 64bit)
-  void reset_last_Java_frame(bool clear_fp, bool clear_pc);
+  void reset_last_Java_frame(bool clear_fp);
 
   // Stores
   void store_check(Register obj);                // store check for obj - register is destroyed afterwards
--- a/src/cpu/x86/vm/runtime_x86_32.cpp	Fri Aug 19 20:38:30 2016 +0200
+++ b/src/cpu/x86/vm/runtime_x86_32.cpp	Fri Aug 19 14:33:52 2016 -0700
@@ -117,7 +117,7 @@
   // No registers to map, rbp is known implicitly
   oop_maps->add_gc_map( __ pc() - start,  new OopMap( framesize, 0 ));
   __ get_thread(rcx);
-  __ reset_last_Java_frame(rcx, false, false);
+  __ reset_last_Java_frame(rcx, false);
 
   // Restore callee-saved registers
   __ movptr(rbp, Address(rsp, rbp_off * wordSize));
--- a/src/cpu/x86/vm/sharedRuntime_x86_32.cpp	Fri Aug 19 20:38:30 2016 +0200
+++ b/src/cpu/x86/vm/sharedRuntime_x86_32.cpp	Fri Aug 19 14:33:52 2016 -0700
@@ -1330,7 +1330,7 @@
   __ increment(rsp, wordSize);
 
   __ get_thread(thread);
-  __ reset_last_Java_frame(thread, false, true);
+  __ reset_last_Java_frame(thread, false);
 
   save_or_restore_arguments(masm, stack_slots, total_in_args,
                             arg_save_area, NULL, in_regs, in_sig_bt);
@@ -2224,7 +2224,7 @@
 
   // We can finally stop using that last_Java_frame we setup ages ago
 
-  __ reset_last_Java_frame(thread, false, true);
+  __ reset_last_Java_frame(thread, false);
 
   // Unpack oop result
   if (ret_type == T_OBJECT || ret_type == T_ARRAY) {
@@ -2553,7 +2553,7 @@
   __ pop(rcx);
 
   __ get_thread(rcx);
-  __ reset_last_Java_frame(rcx, false, false);
+  __ reset_last_Java_frame(rcx, false);
 
   // Load UnrollBlock into EDI
   __ mov(rdi, rax);
@@ -2702,7 +2702,7 @@
   __ push(rax);
 
   __ get_thread(rcx);
-  __ reset_last_Java_frame(rcx, false, false);
+  __ reset_last_Java_frame(rcx, false);
 
   // Collect return values
   __ movptr(rax,Address(rsp, (RegisterSaver::raxOffset() + additional_words + 1)*wordSize));
@@ -2806,7 +2806,7 @@
 
   __ get_thread(rcx);
 
-  __ reset_last_Java_frame(rcx, false, false);
+  __ reset_last_Java_frame(rcx, false);
 
   // Load UnrollBlock into EDI
   __ movptr(rdi, rax);
@@ -2912,7 +2912,7 @@
   oop_maps->add_gc_map( __ pc()-start, new OopMap( framesize, 0 ) );
 
   __ get_thread(rdi);
-  __ reset_last_Java_frame(rdi, true, false);
+  __ reset_last_Java_frame(rdi, true);
 
   // Pop self-frame.
   __ leave();     // Epilog!
@@ -3007,7 +3007,7 @@
 
   // Clear last_Java_sp again
   __ get_thread(java_thread);
-  __ reset_last_Java_frame(java_thread, false, false);
+  __ reset_last_Java_frame(java_thread, false);
 
   __ cmpptr(Address(java_thread, Thread::pending_exception_offset()), (int32_t)NULL_WORD);
   __ jcc(Assembler::equal, noException);
@@ -3082,7 +3082,7 @@
   __ addptr(rsp, wordSize);
 
   // clear last_Java_sp
-  __ reset_last_Java_frame(thread, true, false);
+  __ reset_last_Java_frame(thread, true);
   // check for pending exceptions
   Label pending;
   __ cmpptr(Address(thread, Thread::pending_exception_offset()), (int32_t)NULL_WORD);
--- a/src/cpu/x86/vm/sharedRuntime_x86_64.cpp	Fri Aug 19 20:38:30 2016 +0200
+++ b/src/cpu/x86/vm/sharedRuntime_x86_64.cpp	Fri Aug 19 14:33:52 2016 -0700
@@ -1461,7 +1461,7 @@
   __ mov(rsp, r12); // restore sp
   __ reinit_heapbase();
 
-  __ reset_last_Java_frame(false, true);
+  __ reset_last_Java_frame(false);
 
   save_or_restore_arguments(masm, stack_slots, total_in_args,
                             arg_save_area, NULL, in_regs, in_sig_bt);
@@ -2577,7 +2577,7 @@
     restore_native_result(masm, ret_type, stack_slots);
   }
 
-  __ reset_last_Java_frame(false, true);
+  __ reset_last_Java_frame(false);
 
   // Unpack oop result
   if (ret_type == T_OBJECT || ret_type == T_ARRAY) {
@@ -2849,7 +2849,7 @@
     __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, Deoptimization::uncommon_trap)));
     oop_maps->add_gc_map( __ pc()-start, map->deep_copy());
 
-    __ reset_last_Java_frame(false, false);
+    __ reset_last_Java_frame(false);
 
     __ jmp(after_fetch_unroll_info_call);
   } // EnableJVMCI
@@ -2939,7 +2939,7 @@
   // find any register it might need.
   oop_maps->add_gc_map(__ pc() - start, map);
 
-  __ reset_last_Java_frame(false, false);
+  __ reset_last_Java_frame(false);
 
 #if INCLUDE_JVMCI
   if (EnableJVMCI) {
@@ -3087,7 +3087,7 @@
                        new OopMap( frame_size_in_words, 0 ));
 
   // Clear fp AND pc
-  __ reset_last_Java_frame(true, true);
+  __ reset_last_Java_frame(true);
 
   // Collect return values
   __ movdbl(xmm0, Address(rsp, RegisterSaver::xmm0_offset_in_bytes()));
@@ -3164,7 +3164,7 @@
 
   oop_maps->add_gc_map(__ pc() - start, map);
 
-  __ reset_last_Java_frame(false, false);
+  __ reset_last_Java_frame(false);
 
   // Load UnrollBlock* into rdi
   __ mov(rdi, rax);
@@ -3281,7 +3281,7 @@
   oop_maps->add_gc_map(the_pc - start, new OopMap(SimpleRuntimeFrame::framesize, 0));
 
   // Clear fp AND pc
-  __ reset_last_Java_frame(true, true);
+  __ reset_last_Java_frame(true);
 
   // Pop self-frame.
   __ leave();                 // Epilog
@@ -3364,7 +3364,7 @@
 
   Label noException;
 
-  __ reset_last_Java_frame(false, false);
+  __ reset_last_Java_frame(false);
 
   __ cmpptr(Address(r15_thread, Thread::pending_exception_offset()), (int32_t)NULL_WORD);
   __ jcc(Assembler::equal, noException);
@@ -3434,7 +3434,7 @@
   // rax contains the address we are going to jump to assuming no exception got installed
 
   // clear last_Java_sp
-  __ reset_last_Java_frame(false, false);
+  __ reset_last_Java_frame(false);
   // check for pending exceptions
   Label pending;
   __ cmpptr(Address(r15_thread, Thread::pending_exception_offset()), (int32_t)NULL_WORD);
@@ -3809,7 +3809,7 @@
 
   oop_maps->add_gc_map(the_pc - start, new OopMap(SimpleRuntimeFrame::framesize, 0));
 
-  __ reset_last_Java_frame(false, true);
+  __ reset_last_Java_frame(false);
 
   // Restore callee-saved registers
 
--- a/src/cpu/x86/vm/stubGenerator_x86_32.cpp	Fri Aug 19 20:38:30 2016 +0200
+++ b/src/cpu/x86/vm/stubGenerator_x86_32.cpp	Fri Aug 19 14:33:52 2016 -0700
@@ -3766,7 +3766,7 @@
     // however can use the register value directly if it is callee saved.
     __ get_thread(java_thread);
 
-    __ reset_last_Java_frame(java_thread, true, false);
+    __ reset_last_Java_frame(java_thread, true);
 
     __ leave(); // required for proper stackwalking of RuntimeStub frame
 
--- a/src/cpu/x86/vm/stubGenerator_x86_64.cpp	Fri Aug 19 20:38:30 2016 +0200
+++ b/src/cpu/x86/vm/stubGenerator_x86_64.cpp	Fri Aug 19 14:33:52 2016 -0700
@@ -5018,7 +5018,7 @@
 
     oop_maps->add_gc_map(the_pc - start, map);
 
-    __ reset_last_Java_frame(true, true);
+    __ reset_last_Java_frame(true);
 
     __ leave(); // required for proper stackwalking of RuntimeStub frame
 
--- a/src/cpu/x86/vm/templateInterpreterGenerator_x86.cpp	Fri Aug 19 20:38:30 2016 +0200
+++ b/src/cpu/x86/vm/templateInterpreterGenerator_x86.cpp	Fri Aug 19 14:33:52 2016 -0700
@@ -1167,7 +1167,7 @@
   __ movl(Address(thread, JavaThread::thread_state_offset()), _thread_in_Java);
 
   // reset_last_Java_frame
-  __ reset_last_Java_frame(thread, true, true);
+  __ reset_last_Java_frame(thread, true);
 
   // reset handle block
   __ movptr(t, Address(thread, JavaThread::active_handles_offset()));
@@ -1659,7 +1659,7 @@
   __ set_last_Java_frame(noreg, rbp, __ pc());
   __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::popframe_move_outgoing_args), r15_thread, c_rarg1, c_rarg2);
 #endif
-  __ reset_last_Java_frame(thread, true, true);
+  __ reset_last_Java_frame(thread, true);
 
   // Restore the last_sp and null it out
   __ movptr(rsp, Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize));
--- a/src/cpu/x86/vm/x86_64.ad	Fri Aug 19 20:38:30 2016 +0200
+++ b/src/cpu/x86/vm/x86_64.ad	Fri Aug 19 14:33:52 2016 -0700
@@ -986,7 +986,7 @@
   emit_opcode(cbuf, 0x58 | RBP_enc);
 
   if (StackReservedPages > 0 && C->has_reserved_stack_access()) {
-    __ reserved_stack_check(); 
+    __ reserved_stack_check();
   }
 
   if (do_polling() && C->is_method_compilation()) {
@@ -7355,7 +7355,7 @@
             "movzbl  $res, $res" %}
   opcode(0x0F, 0xB0);
   ins_encode(lock_prefix,
-             REX_reg_mem(newval, mem_ptr),
+             REX_breg_mem(newval, mem_ptr),
              OpcP, OpcS,
              reg_mem(newval, mem_ptr),
              REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete
@@ -7380,7 +7380,7 @@
   opcode(0x0F, 0xB1);
   ins_encode(lock_prefix,
              SizePrefix,
-             REX_reg_mem(newval, mem_ptr),          
+             REX_reg_mem(newval, mem_ptr),
              OpcP, OpcS,
              reg_mem(newval, mem_ptr),
              REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete
@@ -7424,7 +7424,7 @@
             "If rax == $mem_ptr then store $newval into $mem_ptr\n\t"  %}
   opcode(0x0F, 0xB0);
   ins_encode(lock_prefix,
-             REX_reg_mem(newval, mem_ptr),
+             REX_breg_mem(newval, mem_ptr),
              OpcP, OpcS,
              reg_mem(newval, mem_ptr) // lock cmpxchg
              );
--- a/src/os_cpu/bsd_x86/vm/thread_bsd_x86.cpp	Fri Aug 19 20:38:30 2016 +0200
+++ b/src/os_cpu/bsd_x86/vm/thread_bsd_x86.cpp	Fri Aug 19 14:33:52 2016 -0700
@@ -45,7 +45,7 @@
 
   // If we have a last_Java_frame, then we should use it even if
   // isInJava == true.  It should be more reliable than ucontext info.
-  if (jt->has_last_Java_frame()) {
+  if (jt->has_last_Java_frame() && jt->frame_anchor()->walkable()) {
     *fr_addr = jt->pd_last_frame();
     return true;
   }
--- a/src/os_cpu/bsd_x86/vm/thread_bsd_x86.hpp	Fri Aug 19 20:38:30 2016 +0200
+++ b/src/os_cpu/bsd_x86/vm/thread_bsd_x86.hpp	Fri Aug 19 14:33:52 2016 -0700
@@ -32,12 +32,8 @@
 
   frame pd_last_frame() {
     assert(has_last_Java_frame(), "must have last_Java_sp() when suspended");
-    if (_anchor.last_Java_pc() != NULL) {
-      return frame(_anchor.last_Java_sp(), _anchor.last_Java_fp(), _anchor.last_Java_pc());
-    } else {
-      // This will pick up pc from sp
-      return frame(_anchor.last_Java_sp(), _anchor.last_Java_fp());
-    }
+    vmassert(_anchor.last_Java_pc() != NULL, "not walkable");
+    return frame(_anchor.last_Java_sp(), _anchor.last_Java_fp(), _anchor.last_Java_pc());
   }
 
  public:
--- a/src/os_cpu/linux_aarch64/vm/thread_linux_aarch64.cpp	Fri Aug 19 20:38:30 2016 +0200
+++ b/src/os_cpu/linux_aarch64/vm/thread_linux_aarch64.cpp	Fri Aug 19 14:33:52 2016 -0700
@@ -47,7 +47,7 @@
 
   // If we have a last_Java_frame, then we should use it even if
   // isInJava == true.  It should be more reliable than ucontext info.
-  if (jt->has_last_Java_frame()) {
+  if (jt->has_last_Java_frame() && jt->frame_anchor()->walkable()) {
     *fr_addr = jt->pd_last_frame();
     return true;
   }
--- a/src/os_cpu/linux_aarch64/vm/thread_linux_aarch64.hpp	Fri Aug 19 20:38:30 2016 +0200
+++ b/src/os_cpu/linux_aarch64/vm/thread_linux_aarch64.hpp	Fri Aug 19 14:33:52 2016 -0700
@@ -43,12 +43,7 @@
 
   frame pd_last_frame() {
     assert(has_last_Java_frame(), "must have last_Java_sp() when suspended");
-    if (_anchor.last_Java_pc() != NULL) {
-      return frame(_anchor.last_Java_sp(), _anchor.last_Java_fp(), _anchor.last_Java_pc());
-    } else {
-      // This will pick up pc from sp
-      return frame(_anchor.last_Java_sp(), _anchor.last_Java_fp());
-    }
+    return frame(_anchor.last_Java_sp(), _anchor.last_Java_fp(), _anchor.last_Java_pc());
   }
 
  public:
--- a/src/os_cpu/linux_x86/vm/thread_linux_x86.cpp	Fri Aug 19 20:38:30 2016 +0200
+++ b/src/os_cpu/linux_x86/vm/thread_linux_x86.cpp	Fri Aug 19 14:33:52 2016 -0700
@@ -46,7 +46,7 @@
 
   // If we have a last_Java_frame, then we should use it even if
   // isInJava == true.  It should be more reliable than ucontext info.
-  if (jt->has_last_Java_frame()) {
+  if (jt->has_last_Java_frame() && jt->frame_anchor()->walkable()) {
     *fr_addr = jt->pd_last_frame();
     return true;
   }
--- a/src/os_cpu/linux_x86/vm/thread_linux_x86.hpp	Fri Aug 19 20:38:30 2016 +0200
+++ b/src/os_cpu/linux_x86/vm/thread_linux_x86.hpp	Fri Aug 19 14:33:52 2016 -0700
@@ -32,12 +32,8 @@
 
   frame pd_last_frame() {
     assert(has_last_Java_frame(), "must have last_Java_sp() when suspended");
-    if (_anchor.last_Java_pc() != NULL) {
-      return frame(_anchor.last_Java_sp(), _anchor.last_Java_fp(), _anchor.last_Java_pc());
-    } else {
-      // This will pick up pc from sp
-      return frame(_anchor.last_Java_sp(), _anchor.last_Java_fp());
-    }
+    vmassert(_anchor.last_Java_pc() != NULL, "not walkable");
+    return frame(_anchor.last_Java_sp(), _anchor.last_Java_fp(), _anchor.last_Java_pc());
   }
 
  public:
--- a/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp	Fri Aug 19 20:38:30 2016 +0200
+++ b/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp	Fri Aug 19 14:33:52 2016 -0700
@@ -274,8 +274,14 @@
       // stack overflow handling
       return false;
     } else {
-      *fr = os::fetch_frame_from_ucontext(thread, uc);
-      *fr = frame(fr->sender_sp(), fr->sp());
+      // Returned frame will be the caller of the method that faults on the stack bang.
+      // Register window not yet rotated (happens at SAVE after stack bang), so there is no new
+      // frame to go with the faulting PC. Using caller SP that is still in SP, and caller PC
+      // that was written to O7 at call.
+      intptr_t* sp = os::Solaris::ucontext_get_sp(uc);
+      address pc = (address)uc->uc_mcontext.gregs[REG_O7];
+      *fr = frame(sp, frame::unpatchable, pc);
+
       if (!fr->is_java_frame()) {
         assert(fr->safe_for_sender(thread), "Safety check");
         *fr = fr->java_sender();
--- a/src/os_cpu/solaris_x86/vm/thread_solaris_x86.cpp	Fri Aug 19 20:38:30 2016 +0200
+++ b/src/os_cpu/solaris_x86/vm/thread_solaris_x86.cpp	Fri Aug 19 14:33:52 2016 -0700
@@ -45,9 +45,8 @@
   assert(this->is_Java_thread(), "must be JavaThread");
   JavaThread* jt = (JavaThread *)this;
 
-  // last_Java_frame is always walkable and safe use it if we have it
-
-  if (jt->has_last_Java_frame()) {
+  // There is small window where last_Java_frame is not walkable or safe
+  if (jt->has_last_Java_frame() && jt->frame_anchor()->walkable()) {
     *fr_addr = jt->pd_last_frame();
     return true;
   }
--- a/src/os_cpu/solaris_x86/vm/thread_solaris_x86.hpp	Fri Aug 19 20:38:30 2016 +0200
+++ b/src/os_cpu/solaris_x86/vm/thread_solaris_x86.hpp	Fri Aug 19 14:33:52 2016 -0700
@@ -30,12 +30,8 @@
 
   frame pd_last_frame() {
     assert(has_last_Java_frame(), "must have last_Java_sp() when suspended");
-    if (_anchor.last_Java_pc() != NULL) {
-      return frame(_anchor.last_Java_sp(), _anchor.last_Java_fp(), _anchor.last_Java_pc());
-    } else {
-      // This will pick up pc from sp
-      return frame(_anchor.last_Java_sp(), _anchor.last_Java_fp());
-    }
+    vmassert(_anchor.last_Java_pc() != NULL, "not walkable");
+    return frame(_anchor.last_Java_sp(), _anchor.last_Java_fp(), _anchor.last_Java_pc());
   }
 
  public:
--- a/src/os_cpu/windows_x86/vm/thread_windows_x86.cpp	Fri Aug 19 20:38:30 2016 +0200
+++ b/src/os_cpu/windows_x86/vm/thread_windows_x86.cpp	Fri Aug 19 14:33:52 2016 -0700
@@ -48,7 +48,7 @@
 
   // If we have a last_Java_frame, then we should use it even if
   // isInJava == true.  It should be more reliable than CONTEXT info.
-  if (jt->has_last_Java_frame()) {
+  if (jt->has_last_Java_frame() && jt->frame_anchor()->walkable()) {
     *fr_addr = jt->pd_last_frame();
     return true;
   }
--- a/src/os_cpu/windows_x86/vm/thread_windows_x86.hpp	Fri Aug 19 20:38:30 2016 +0200
+++ b/src/os_cpu/windows_x86/vm/thread_windows_x86.hpp	Fri Aug 19 14:33:52 2016 -0700
@@ -32,12 +32,8 @@
 
   frame pd_last_frame() {
     assert(has_last_Java_frame(), "must have last_Java_sp() when suspended");
-    if (_anchor.last_Java_pc() != NULL) {
-      return frame(_anchor.last_Java_sp(), _anchor.last_Java_fp(), _anchor.last_Java_pc());
-    } else {
-      // This will pick up pc from sp
-      return frame(_anchor.last_Java_sp(), _anchor.last_Java_fp());
-    }
+    vmassert(_anchor.last_Java_pc() != NULL, "not walkable");
+    return frame(_anchor.last_Java_sp(), _anchor.last_Java_fp(), _anchor.last_Java_pc());
   }
 
  public:
--- a/src/share/vm/jvmci/jvmciEnv.cpp	Fri Aug 19 20:38:30 2016 +0200
+++ b/src/share/vm/jvmci/jvmciEnv.cpp	Fri Aug 19 14:33:52 2016 -0700
@@ -342,7 +342,7 @@
   Symbol* sig_sym  = cpool->signature_ref_at(index);
 
   if (cpool->has_preresolution()
-      || (holder() == SystemDictionary::MethodHandle_klass() &&
+      || ((holder() == SystemDictionary::MethodHandle_klass() || holder() == SystemDictionary::VarHandle_klass()) &&
           MethodHandles::is_signature_polymorphic_name(holder(), name_sym))) {
     // Short-circuit lookups for JSR 292-related call sites.
     // That is, do not rely only on name-based lookups, because they may fail
--- a/src/share/vm/oops/method.cpp	Fri Aug 19 20:38:30 2016 +0200
+++ b/src/share/vm/oops/method.cpp	Fri Aug 19 14:33:52 2016 -0700
@@ -54,6 +54,7 @@
 #include "runtime/compilationPolicy.hpp"
 #include "runtime/frame.inline.hpp"
 #include "runtime/handles.inline.hpp"
+#include "runtime/init.hpp"
 #include "runtime/orderAccess.inline.hpp"
 #include "runtime/relocator.hpp"
 #include "runtime/sharedRuntime.hpp"
@@ -1015,7 +1016,14 @@
   // so making them eagerly shouldn't be too expensive.
   AdapterHandlerEntry* adapter = AdapterHandlerLibrary::get_adapter(mh);
   if (adapter == NULL ) {
-    THROW_MSG_NULL(vmSymbols::java_lang_VirtualMachineError(), "Out of space in CodeCache for adapters");
+    if (!is_init_completed()) {
+      // Don't throw exceptions during VM initialization because java.lang.* classes
+      // might not have been initialized, causing problems when constructing the
+      // Java exception object.
+      vm_exit_during_initialization("Out of space in CodeCache for adapters");
+    } else {
+      THROW_MSG_NULL(vmSymbols::java_lang_VirtualMachineError(), "Out of space in CodeCache for adapters");
+    }
   }
 
   if (mh->is_shared()) {
--- a/test/compiler/profiling/spectrapredefineclass/Agent.java	Fri Aug 19 20:38:30 2016 +0200
+++ b/test/compiler/profiling/spectrapredefineclass/Agent.java	Fri Aug 19 14:33:52 2016 -0700
@@ -24,10 +24,12 @@
 package compiler.profiling.spectrapredefineclass;
 
 import com.sun.tools.attach.VirtualMachine;
+import jdk.test.lib.Utils;
 
 import java.lang.instrument.ClassFileTransformer;
 import java.lang.instrument.Instrumentation;
 import java.lang.management.ManagementFactory;
+import java.nio.file.Paths;
 import java.security.ProtectionDomain;
 
 class A {
@@ -67,8 +69,7 @@
 }
 
 public class Agent implements ClassFileTransformer {
-
-
+    public static final String AGENT_JAR = Paths.get(Utils.TEST_CLASSES, "agent.jar").toString();
     static public boolean m2(A a) {
         boolean res = false;
         if (a.getClass() == B.class) {
@@ -95,7 +96,7 @@
         // Redefine class
         try {
             VirtualMachine vm = VirtualMachine.attach(pid);
-            vm.loadAgent(System.getProperty("test.classes",".") + "/agent.jar", "");
+            vm.loadAgent(AGENT_JAR, "");
             vm.detach();
         } catch (Exception e) {
             throw new RuntimeException(e);
--- a/test/compiler/profiling/spectrapredefineclass/Launcher.java	Fri Aug 19 20:38:30 2016 +0200
+++ b/test/compiler/profiling/spectrapredefineclass/Launcher.java	Fri Aug 19 14:33:52 2016 -0700
@@ -28,7 +28,7 @@
  * @modules java.base/jdk.internal.misc
  *          java.instrument
  *          java.management
- * @build compiler.profiling.spectrapredefineclass_classloaders.Agent
+ * @build compiler.profiling.spectrapredefineclass.Agent
  * @run driver ClassFileInstaller compiler.profiling.spectrapredefineclass.Agent
  * @run driver compiler.profiling.spectrapredefineclass.Launcher
  * @run main/othervm -XX:-TieredCompilation -XX:-BackgroundCompilation
@@ -39,23 +39,33 @@
 
 package compiler.profiling.spectrapredefineclass;
 
-import jdk.test.lib.JDKToolFinder;
+import jdk.test.lib.JDKToolLauncher;
+import jdk.test.lib.OutputAnalyzer;
 
 import java.io.File;
+import java.io.IOException;
 import java.io.PrintWriter;
 
 public class Launcher {
+    private static final String MANIFEST = "MANIFEST.MF";
     public static void main(String[] args) throws Exception  {
+        try (PrintWriter pw = new PrintWriter(MANIFEST)) {
+            pw.println("Agent-Class: " + Agent.class.getName());
+            pw.println("Can-Retransform-Classes: true");
+        }
 
-      PrintWriter pw = new PrintWriter("MANIFEST.MF");
-      pw.println("Agent-Class: " + Launcher.class.getPackage().getName() +".Agent");
-      pw.println("Can-Retransform-Classes: true");
-      pw.close();
+        JDKToolLauncher jar = JDKToolLauncher.create("jar")
+                .addToolArg("cmf")
+                .addToolArg(MANIFEST)
+                .addToolArg(Agent.AGENT_JAR)
+                .addToolArg(Agent.class.getName().replace('.', File.separatorChar) + ".class");
 
-      ProcessBuilder pb = new ProcessBuilder();
-      pb.command(new String[] { JDKToolFinder.getJDKTool("jar"), "cmf", "MANIFEST.MF",
-              System.getProperty("test.classes",".") + "/agent.jar",
-              "compiler/profiling/spectrapredefineclass/Agent.class".replace('/', File.separatorChar)});
-      pb.start().waitFor();
+        ProcessBuilder pb = new ProcessBuilder(jar.getCommand());
+        try {
+            OutputAnalyzer output = new OutputAnalyzer(pb.start());
+            output.shouldHaveExitValue(0);
+        } catch (IOException ex) {
+            throw new Error("TESTBUG: jar failed.", ex);
+        }
     }
 }
--- a/test/compiler/profiling/spectrapredefineclass_classloaders/Agent.java	Fri Aug 19 20:38:30 2016 +0200
+++ b/test/compiler/profiling/spectrapredefineclass_classloaders/Agent.java	Fri Aug 19 14:33:52 2016 -0700
@@ -24,6 +24,7 @@
 package compiler.profiling.spectrapredefineclass_classloaders;
 
 import com.sun.tools.attach.VirtualMachine;
+import jdk.test.lib.Utils;
 
 import java.lang.instrument.ClassFileTransformer;
 import java.lang.instrument.Instrumentation;
@@ -32,14 +33,16 @@
 import java.net.MalformedURLException;
 import java.net.URL;
 import java.net.URLClassLoader;
+import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.security.ProtectionDomain;
 
 public class Agent implements ClassFileTransformer {
+    public static final String AGENT_JAR = Paths.get(Utils.TEST_CLASSES, "agent.jar").toString();
     public static ClassLoader newClassLoader() {
         try {
             return new URLClassLoader(new URL[] {
-                    Paths.get(System.getProperty("test.classes",".")).toUri().toURL(),
+                    Paths.get(Utils.TEST_CLASSES).toUri().toURL(),
             }, null);
         } catch (MalformedURLException e){
             throw new RuntimeException("Unexpected URL conversion failure", e);
@@ -76,7 +79,7 @@
         for (int i = 0; i < 2; i++) {
             try {
                 VirtualMachine vm = VirtualMachine.attach(pid);
-                vm.loadAgent(System.getProperty("test.classes",".") + "/agent.jar", "");
+                vm.loadAgent(AGENT_JAR, "");
                 vm.detach();
             } catch (Exception e) {
                 throw new RuntimeException(e);
--- a/test/compiler/profiling/spectrapredefineclass_classloaders/Launcher.java	Fri Aug 19 20:38:30 2016 +0200
+++ b/test/compiler/profiling/spectrapredefineclass_classloaders/Launcher.java	Fri Aug 19 14:33:52 2016 -0700
@@ -39,26 +39,36 @@
  *                   -XX:ReservedCodeCacheSize=3M
  *                   compiler.profiling.spectrapredefineclass_classloaders.Agent
  */
+
 package compiler.profiling.spectrapredefineclass_classloaders;
 
-import jdk.test.lib.JDKToolFinder;
+import jdk.test.lib.JDKToolLauncher;
+import jdk.test.lib.OutputAnalyzer;
 
 import java.io.File;
+import java.io.IOException;
 import java.io.PrintWriter;
 
 public class Launcher {
-    public static void main(String[] args) throws Exception {
+    private static final String MANIFEST = "MANIFEST.MF";
+    public static void main(String[] args) throws Exception  {
+        try (PrintWriter pw = new PrintWriter(MANIFEST)) {
+            pw.println("Agent-Class: " + Agent.class.getName());
+            pw.println("Can-Retransform-Classes: true");
+        }
 
-        PrintWriter pw = new PrintWriter("MANIFEST.MF");
+        JDKToolLauncher jar = JDKToolLauncher.create("jar")
+                .addToolArg("cmf")
+                .addToolArg(MANIFEST)
+                .addToolArg(Agent.AGENT_JAR)
+                .addToolArg(Agent.class.getName().replace('.', File.separatorChar) + ".class");
 
-        pw.println("Agent-Class: " + Launcher.class.getPackage().getName() + ".Agent");
-        pw.println("Can-Retransform-Classes: true");
-        pw.close();
-
-        ProcessBuilder pb = new ProcessBuilder();
-        pb.command(new String[]{JDKToolFinder.getJDKTool("jar"), "cmf", "MANIFEST.MF",
-                System.getProperty("test.classes", ".") + "/agent.jar",
-                "compiler/profiling/spectrapredefineclass/Agent.class".replace('/', File.separatorChar)});
-        pb.start().waitFor();
+        ProcessBuilder pb = new ProcessBuilder(jar.getCommand());
+        try {
+            OutputAnalyzer output = new OutputAnalyzer(pb.start());
+            output.shouldHaveExitValue(0);
+        } catch (IOException ex) {
+            throw new Error("TESTBUG: jar failed.", ex);
+        }
     }
 }
--- a/test/compiler/startup/StartupOutput.java	Fri Aug 19 20:38:30 2016 +0200
+++ b/test/compiler/startup/StartupOutput.java	Fri Aug 19 14:33:52 2016 -0700
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 8026949
+ * @bug 8026949 8164091
  * @summary Test ensures correct VM output during startup
  * @library /test/lib
  * @modules java.base/jdk.internal.misc
@@ -45,7 +45,14 @@
         pb = ProcessTools.createJavaProcessBuilder("-Xint", "-XX:+DisplayVMOutputToStdout", "-version");
         out = new OutputAnalyzer(pb.start());
         out.shouldNotContain("no space to run compilers");
+        out.shouldHaveExitValue(0);
 
-        out.shouldHaveExitValue(0);
+        pb = ProcessTools.createJavaProcessBuilder("-Xint", "-XX:ReservedCodeCacheSize=1770K", "-XX:InitialCodeCacheSize=4K", "-version");
+        out = new OutputAnalyzer(pb.start());
+        // The VM should not crash but may return an error message because we don't have enough space for adapters
+        int exitCode = out.getExitValue();
+        if (exitCode != 1 && exitCode != 0) {
+            throw new Exception("VM crashed with exit code " + exitCode);
+        }
     }
 }