8156923: [ppc] Implement "JEP 270: Reserved Stack Areas for Critical Sections".
authorgoetz
Fri, 13 May 2016 15:22:48 +0200
changeset 38931 3cf28d630349
parent 38929 1ee62412a66f
child 38932 3a34c2a9b7bc
8156923: [ppc] Implement "JEP 270: Reserved Stack Areas for Critical Sections". Reviewed-by: simonis, dholmes
hotspot/src/cpu/ppc/vm/assembler_ppc.hpp
hotspot/src/cpu/ppc/vm/assembler_ppc.inline.hpp
hotspot/src/cpu/ppc/vm/c1_LIRAssembler_ppc.cpp
hotspot/src/cpu/ppc/vm/globalDefinitions_ppc.hpp
hotspot/src/cpu/ppc/vm/globals_ppc.hpp
hotspot/src/cpu/ppc/vm/interp_masm_ppc_64.cpp
hotspot/src/cpu/ppc/vm/macroAssembler_ppc.cpp
hotspot/src/cpu/ppc/vm/macroAssembler_ppc.hpp
hotspot/src/cpu/ppc/vm/ppc.ad
hotspot/src/cpu/ppc/vm/stubGenerator_ppc.cpp
hotspot/src/os/aix/vm/os_aix.hpp
hotspot/src/os_cpu/aix_ppc/vm/os_aix_ppc.cpp
hotspot/src/os_cpu/linux_ppc/vm/os_linux_ppc.cpp
hotspot/test/runtime/ReservedStack/ReservedStackTest.java
hotspot/test/runtime/ReservedStack/ReservedStackTestCompiler.java
--- a/hotspot/src/cpu/ppc/vm/assembler_ppc.hpp	Thu Jun 02 09:44:41 2016 +0200
+++ b/hotspot/src/cpu/ppc/vm/assembler_ppc.hpp	Fri May 13 15:22:48 2016 +0200
@@ -1,6 +1,6 @@
 /*
- * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2012, 2015 SAP SE. All rights reserved.
+ * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2016 SAP SE. 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
@@ -1530,6 +1530,10 @@
   inline void ld(   Register d, int si16,    Register s1);
   inline void ldu(  Register d, int si16,    Register s1);
 
+  // For convenience. Load pointer into d from b+s1.
+  inline void ld_ptr(Register d, int b, Register s1);
+  DEBUG_ONLY(inline void ld_ptr(Register d, ByteSize b, Register s1);)
+
   //  PPC 1, section 3.3.3 Fixed-Point Store Instructions
   inline void stwx( Register d, Register s1, Register s2);
   inline void stw(  Register d, int si16,    Register s1);
@@ -2194,7 +2198,8 @@
   void add( Register d, RegisterOrConstant roc, Register s1);
   void subf(Register d, RegisterOrConstant roc, Register s1);
   void cmpd(ConditionRegister d, RegisterOrConstant roc, Register s1);
-
+  // Load pointer d from s1+roc.
+  void ld_ptr(Register d, RegisterOrConstant roc, Register s1 = noreg) { ld(d, roc, s1); }
 
   // Emit several instructions to load a 64 bit constant. This issues a fixed
   // instruction pattern so that the constant can be patched later on.
--- a/hotspot/src/cpu/ppc/vm/assembler_ppc.inline.hpp	Thu Jun 02 09:44:41 2016 +0200
+++ b/hotspot/src/cpu/ppc/vm/assembler_ppc.inline.hpp	Fri May 13 15:22:48 2016 +0200
@@ -1,6 +1,6 @@
 /*
- * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2012, 2015 SAP SE. All rights reserved.
+ * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2016 SAP SE. 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
@@ -328,6 +328,9 @@
 inline void Assembler::ldx(  Register d, Register s1, Register s2) { emit_int32(LDX_OPCODE | rt(d) | ra0mem(s1) | rb(s2));}
 inline void Assembler::ldu(  Register d, int si16,    Register s1) { assert(d != s1, "according to ibm manual"); emit_int32(LDU_OPCODE | rt(d) | ds(si16) | rta0mem(s1));}
 
+inline void Assembler::ld_ptr(Register d, int b, Register s1) { ld(d, b, s1); }
+DEBUG_ONLY(inline void Assembler::ld_ptr(Register d, ByteSize b, Register s1) { ld(d, in_bytes(b), s1); })
+
 //  PPC 1, section 3.3.3 Fixed-Point Store Instructions
 inline void Assembler::stwx( Register d, Register s1, Register s2) { emit_int32(STWX_OPCODE | rs(d) | ra0mem(s1) | rb(s2));}
 inline void Assembler::stw(  Register d, int si16,    Register s1) { emit_int32(STW_OPCODE  | rs(d) | d1(si16)   | ra0mem(s1));}
--- a/hotspot/src/cpu/ppc/vm/c1_LIRAssembler_ppc.cpp	Thu Jun 02 09:44:41 2016 +0200
+++ b/hotspot/src/cpu/ppc/vm/c1_LIRAssembler_ppc.cpp	Fri May 13 15:22:48 2016 +0200
@@ -1,6 +1,6 @@
 /*
- * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2012, 2015 SAP SE. All rights reserved.
+ * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2016 SAP SE. 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
@@ -1242,7 +1242,7 @@
 
 
 void LIR_Assembler::return_op(LIR_Opr result) {
-  const Register return_pc        = R11;
+  const Register return_pc        = R31;  // Must survive C-call to enable_stack_reserved_zone().
   const Register polling_page     = R12;
 
   // Pop the stack before the safepoint code.
@@ -1265,6 +1265,10 @@
   // Move return pc to LR.
   __ mtlr(return_pc);
 
+  if (StackReservedPages > 0 && compilation()->has_reserved_stack_access()) {
+    __ reserved_stack_check(return_pc);
+  }
+
   // We need to mark the code position where the load from the safepoint
   // polling page was emitted as relocInfo::poll_return_type here.
   __ relocate(relocInfo::poll_return_type);
--- a/hotspot/src/cpu/ppc/vm/globalDefinitions_ppc.hpp	Thu Jun 02 09:44:41 2016 +0200
+++ b/hotspot/src/cpu/ppc/vm/globalDefinitions_ppc.hpp	Fri May 13 15:22:48 2016 +0200
@@ -1,6 +1,6 @@
 /*
- * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2012, 2015 SAP SE. All rights reserved.
+ * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2016 SAP SE. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -52,4 +52,6 @@
 #define INCLUDE_RTM_OPT 1
 #endif
 
+#define SUPPORT_RESERVED_STACK_AREA
+
 #endif // CPU_PPC_VM_GLOBALDEFINITIONS_PPC_HPP
--- a/hotspot/src/cpu/ppc/vm/globals_ppc.hpp	Thu Jun 02 09:44:41 2016 +0200
+++ b/hotspot/src/cpu/ppc/vm/globals_ppc.hpp	Fri May 13 15:22:48 2016 +0200
@@ -43,7 +43,7 @@
 #define DEFAULT_STACK_YELLOW_PAGES (6)
 #define DEFAULT_STACK_RED_PAGES (1)
 #define DEFAULT_STACK_SHADOW_PAGES (6 DEBUG_ONLY(+2))
-#define DEFAULT_STACK_RESERVED_PAGES (0)
+#define DEFAULT_STACK_RESERVED_PAGES (1)
 
 #define MIN_STACK_YELLOW_PAGES DEFAULT_STACK_YELLOW_PAGES
 #define MIN_STACK_RED_PAGES DEFAULT_STACK_RED_PAGES
--- a/hotspot/src/cpu/ppc/vm/interp_masm_ppc_64.cpp	Thu Jun 02 09:44:41 2016 +0200
+++ b/hotspot/src/cpu/ppc/vm/interp_masm_ppc_64.cpp	Fri May 13 15:22:48 2016 +0200
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2012, 2015 SAP SE. All rights reserved.
+ * Copyright (c) 2012, 2016 SAP SE. 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
@@ -480,6 +480,7 @@
 
 void InterpreterMacroAssembler::generate_stack_overflow_check_with_compare_and_throw(Register Rmem_frame_size, Register Rscratch1) {
   Label done;
+  BLOCK_COMMENT("stack_overflow_check_with_compare_and_throw {");
   sub(Rmem_frame_size, R1_SP, Rmem_frame_size);
   ld(Rscratch1, thread_(stack_overflow_limit));
   cmpld(CCR0/*is_stack_overflow*/, Rmem_frame_size, Rscratch1);
@@ -501,6 +502,7 @@
 
   align(32, 12);
   bind(done);
+  BLOCK_COMMENT("} stack_overflow_check_with_compare_and_throw");
 }
 
 // Separate these two to allow for delay slot in middle.
@@ -805,16 +807,41 @@
 void InterpreterMacroAssembler::remove_activation(TosState state,
                                                   bool throw_monitor_exception,
                                                   bool install_monitor_exception) {
+  BLOCK_COMMENT("remove_activation {");
   unlock_if_synchronized_method(state, throw_monitor_exception, install_monitor_exception);
 
   // Save result (push state before jvmti call and pop it afterwards) and notify jvmti.
   notify_method_exit(false, state, NotifyJVMTI, true);
 
+  BLOCK_COMMENT("reserved_stack_check:");
+  if (StackReservedPages > 0) {
+    // Test if reserved zone needs to be enabled.
+    Label no_reserved_zone_enabling;
+
+    // Compare frame pointers. There is no good stack pointer, as with stack
+    // frame compression we can get different SPs when we do calls. A subsequent
+    // call could have a smaller SP, so that this compare succeeds for an
+    // inner call of the method annotated with ReservedStack.
+    ld_ptr(R0, JavaThread::reserved_stack_activation_offset(), R16_thread);
+    ld_ptr(R11_scratch1, _abi(callers_sp), R1_SP); // Load frame pointer.
+    cmpld(CCR0, R11_scratch1, R0);
+    blt_predict_taken(CCR0, no_reserved_zone_enabling);
+
+    // Enable reserved zone again, throw stack overflow exception.
+    call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::enable_stack_reserved_zone), R16_thread);
+    call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_delayed_StackOverflowError));
+
+    should_not_reach_here();
+
+    bind(no_reserved_zone_enabling);
+  }
+
   verify_oop(R17_tos, state);
   verify_thread();
 
   merge_frames(/*top_frame_sp*/ R21_sender_SP, /*return_pc*/ R0, R11_scratch1, R12_scratch2);
   mtlr(R0);
+  BLOCK_COMMENT("} remove_activation");
 }
 
 // Lock object
--- a/hotspot/src/cpu/ppc/vm/macroAssembler_ppc.cpp	Thu Jun 02 09:44:41 2016 +0200
+++ b/hotspot/src/cpu/ppc/vm/macroAssembler_ppc.cpp	Fri May 13 15:22:48 2016 +0200
@@ -1400,6 +1400,28 @@
 #endif
 }
 
+void MacroAssembler::reserved_stack_check(Register return_pc) {
+  // Test if reserved zone needs to be enabled.
+  Label no_reserved_zone_enabling;
+
+  ld_ptr(R0, JavaThread::reserved_stack_activation_offset(), R16_thread);
+  cmpld(CCR0, R1_SP, R0);
+  blt_predict_taken(CCR0, no_reserved_zone_enabling);
+
+  // Enable reserved zone again, throw stack overflow exception.
+  push_frame_reg_args(0, R0);
+  call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::enable_stack_reserved_zone), R16_thread);
+  pop_frame();
+  mtlr(return_pc);
+  load_const_optimized(R0, StubRoutines::throw_delayed_StackOverflowError_entry());
+  mtctr(R0);
+  bctr();
+
+  should_not_reach_here();
+
+  bind(no_reserved_zone_enabling);
+}
+
 // CmpxchgX sets condition register to cmpX(current, compare).
 void MacroAssembler::cmpxchgw(ConditionRegister flag, Register dest_current_value,
                               Register compare_value, Register exchange_value,
--- a/hotspot/src/cpu/ppc/vm/macroAssembler_ppc.hpp	Thu Jun 02 09:44:41 2016 +0200
+++ b/hotspot/src/cpu/ppc/vm/macroAssembler_ppc.hpp	Fri May 13 15:22:48 2016 +0200
@@ -411,6 +411,10 @@
   // stdux, return the banged address. Otherwise, return 0.
   static address get_stack_bang_address(int instruction, void* ucontext);
 
+  // Check for reserved stack access in method being exited. If the reserved
+  // stack area was accessed, protect it again and throw StackOverflowError.
+  void reserved_stack_check(Register return_pc);
+
   // Atomics
   // CmpxchgX sets condition register to cmpX(current, compare).
   // (flag == ne) => (dest_current_value != compare_value), (!swapped)
--- a/hotspot/src/cpu/ppc/vm/ppc.ad	Thu Jun 02 09:44:41 2016 +0200
+++ b/hotspot/src/cpu/ppc/vm/ppc.ad	Fri May 13 15:22:48 2016 +0200
@@ -1432,7 +1432,7 @@
 
   const bool method_needs_polling = do_polling() && C->is_method_compilation();
   const bool method_is_frameless  = false /* TODO: PPC port C->is_frameless_method()*/;
-  const Register return_pc        = R11;
+  const Register return_pc        = R31;  // Must survive C-call to enable_stack_reserved_zone().
   const Register polling_page     = R12;
 
   if (!method_is_frameless) {
@@ -1456,6 +1456,10 @@
     __ addi(R1_SP, R1_SP, (int)framesize);
   }
 
+  if (StackReservedPages > 0 && C->has_reserved_stack_access()) {
+    __ reserved_stack_check(return_pc);
+  }
+
   if (method_needs_polling) {
     // We need to mark the code position where the load from the safepoint
     // polling page was emitted as relocInfo::poll_return_type here.
--- a/hotspot/src/cpu/ppc/vm/stubGenerator_ppc.cpp	Thu Jun 02 09:44:41 2016 +0200
+++ b/hotspot/src/cpu/ppc/vm/stubGenerator_ppc.cpp	Fri May 13 15:22:48 2016 +0200
@@ -3082,6 +3082,9 @@
     StubRoutines::_throw_StackOverflowError_entry   =
       generate_throw_exception("StackOverflowError throw_exception",
                                CAST_FROM_FN_PTR(address, SharedRuntime::throw_StackOverflowError), false);
+    StubRoutines::_throw_delayed_StackOverflowError_entry =
+      generate_throw_exception("delayed StackOverflowError throw_exception",
+                               CAST_FROM_FN_PTR(address, SharedRuntime::throw_delayed_StackOverflowError), false);
 
     // CRC32 Intrinsics.
     if (UseCRC32Intrinsics) {
--- a/hotspot/src/os/aix/vm/os_aix.hpp	Thu Jun 02 09:44:41 2016 +0200
+++ b/hotspot/src/os/aix/vm/os_aix.hpp	Fri May 13 15:22:48 2016 +0200
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2013, 2015 SAP SE. All rights reserved.
+ * Copyright (c) 2013, 2016 SAP SE. 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
@@ -128,6 +128,8 @@
   // Set PC into context. Needed for continuation after signal.
   static void ucontext_set_pc(ucontext_t* uc, address pc);
 
+  static bool get_frame_at_stack_banging_point(JavaThread* thread, ucontext_t* uc, frame* fr);
+
   // This boolean allows users to forward their own non-matching signals
   // to JVM_handle_aix_signal, harmlessly.
   static bool signal_handlers_are_installed;
--- a/hotspot/src/os_cpu/aix_ppc/vm/os_aix_ppc.cpp	Thu Jun 02 09:44:41 2016 +0200
+++ b/hotspot/src/os_cpu/aix_ppc/vm/os_aix_ppc.cpp	Fri May 13 15:22:48 2016 +0200
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2012, 2014 SAP SE. All rights reserved.
+ * Copyright (c) 2012, 2016 SAP SE. 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
@@ -24,7 +24,7 @@
  */
 
 // no precompiled headers
-#include "assembler_ppc.inline.hpp"
+#include "asm/assembler.inline.hpp"
 #include "classfile/classLoader.hpp"
 #include "classfile/systemDictionary.hpp"
 #include "classfile/vmSymbols.hpp"
@@ -145,6 +145,41 @@
   return fr;
 }
 
+bool os::Aix::get_frame_at_stack_banging_point(JavaThread* thread, ucontext_t* uc, frame* fr) {
+  address pc = (address) os::Aix::ucontext_get_pc(uc);
+  if (Interpreter::contains(pc)) {
+    // Interpreter performs stack banging after the fixed frame header has
+    // been generated while the compilers perform it before. To maintain
+    // semantic consistency between interpreted and compiled frames, the
+    // method returns the Java sender of the current frame.
+    *fr = os::fetch_frame_from_context(uc);
+    if (!fr->is_first_java_frame()) {
+      assert(fr->safe_for_sender(thread), "Safety check");
+      *fr = fr->java_sender();
+    }
+  } else {
+    // More complex code with compiled code.
+    assert(!Interpreter::contains(pc), "Interpreted methods should have been handled above");
+    CodeBlob* cb = CodeCache::find_blob(pc);
+    if (cb == NULL || !cb->is_nmethod() || cb->is_frame_complete_at(pc)) {
+      // Not sure where the pc points to, fallback to default
+      // stack overflow handling. In compiled code, we bang before
+      // the frame is complete.
+      return false;
+    } else {
+      intptr_t* sp = os::Aix::ucontext_get_sp(uc);
+      *fr = frame(sp, (address)*sp);
+      if (!fr->is_java_frame()) {
+        assert(fr->safe_for_sender(thread), "Safety check");
+        assert(!fr->is_first_frame(), "Safety check");
+        *fr = fr->java_sender();
+      }
+    }
+  }
+  assert(fr->is_java_frame(), "Safety check");
+  return true;
+}
+
 frame os::get_sender_for_C_frame(frame* fr) {
   if (*fr->sp() == NULL) {
     // fr is the last C frame
@@ -246,14 +281,32 @@
       // to continue with yellow zone disabled, but that doesn't buy us much and prevents
       // hs_err_pid files.
       if (thread->in_stack_yellow_reserved_zone(addr)) {
-        thread->disable_stack_yellow_reserved_zone();
         if (thread->thread_state() == _thread_in_Java) {
+            if (thread->in_stack_reserved_zone(addr)) {
+              frame fr;
+              if (os::Aix::get_frame_at_stack_banging_point(thread, uc, &fr)) {
+                assert(fr.is_java_frame(), "Must be a Javac frame");
+                frame activation =
+                  SharedRuntime::look_for_reserved_stack_annotated_method(thread, fr);
+                if (activation.sp() != NULL) {
+                  thread->disable_stack_reserved_zone();
+                  if (activation.is_interpreted_frame()) {
+                    thread->set_reserved_stack_activation((address)activation.fp());
+                  } else {
+                    thread->set_reserved_stack_activation((address)activation.unextended_sp());
+                  }
+                  return 1;
+                }
+              }
+            }
           // Throw a stack overflow exception.
           // Guard pages will be reenabled while unwinding the stack.
+          thread->disable_stack_yellow_reserved_zone();
           stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW);
           goto run_stub;
         } else {
           // Thread was in the vm or native code. Return and try to finish.
+          thread->disable_stack_yellow_reserved_zone();
           return 1;
         }
       } else if (thread->in_stack_red_zone(addr)) {
--- a/hotspot/src/os_cpu/linux_ppc/vm/os_linux_ppc.cpp	Thu Jun 02 09:44:41 2016 +0200
+++ b/hotspot/src/os_cpu/linux_ppc/vm/os_linux_ppc.cpp	Fri May 13 15:22:48 2016 +0200
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2012, 2015 SAP SE. All rights reserved.
+ * Copyright (c) 2012, 2016 SAP SE. 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
@@ -24,7 +24,7 @@
  */
 
 // no precompiled headers
-#include "assembler_ppc.inline.hpp"
+#include "asm/assembler.inline.hpp"
 #include "classfile/classLoader.hpp"
 #include "classfile/systemDictionary.hpp"
 #include "classfile/vmSymbols.hpp"
@@ -157,6 +157,42 @@
   return frame(sp, epc.pc());
 }
 
+bool os::Linux::get_frame_at_stack_banging_point(JavaThread* thread, ucontext_t* uc, frame* fr) {
+  address pc = (address) os::Linux::ucontext_get_pc(uc);
+  if (Interpreter::contains(pc)) {
+    // Interpreter performs stack banging after the fixed frame header has
+    // been generated while the compilers perform it before. To maintain
+    // semantic consistency between interpreted and compiled frames, the
+    // method returns the Java sender of the current frame.
+    *fr = os::fetch_frame_from_context(uc);
+    if (!fr->is_first_java_frame()) {
+      assert(fr->safe_for_sender(thread), "Safety check");
+      *fr = fr->java_sender();
+    }
+  } else {
+    // More complex code with compiled code.
+    assert(!Interpreter::contains(pc), "Interpreted methods should have been handled above");
+    CodeBlob* cb = CodeCache::find_blob(pc);
+    if (cb == NULL || !cb->is_nmethod() || cb->is_frame_complete_at(pc)) {
+      // Not sure where the pc points to, fallback to default
+      // stack overflow handling. In compiled code, we bang before
+      // the frame is complete.
+      return false;
+    } else {
+      intptr_t* fp = os::Linux::ucontext_get_fp(uc);
+      intptr_t* sp = os::Linux::ucontext_get_sp(uc);
+      *fr = frame(sp, (address)*sp);
+      if (!fr->is_java_frame()) {
+        assert(fr->safe_for_sender(thread), "Safety check");
+        assert(!fr->is_first_frame(), "Safety check");
+        *fr = fr->java_sender();
+      }
+    }
+  }
+  assert(fr->is_java_frame(), "Safety check");
+  return true;
+}
+
 frame os::get_sender_for_C_frame(frame* fr) {
   if (*fr->sp() == 0) {
     // fr is the last C frame
@@ -243,13 +279,31 @@
       if (thread->on_local_stack(addr)) {
         // stack overflow
         if (thread->in_stack_yellow_reserved_zone(addr)) {
-          thread->disable_stack_yellow_reserved_zone();
           if (thread->thread_state() == _thread_in_Java) {
+            if (thread->in_stack_reserved_zone(addr)) {
+              frame fr;
+              if (os::Linux::get_frame_at_stack_banging_point(thread, uc, &fr)) {
+                assert(fr.is_java_frame(), "Must be a Javac frame");
+                frame activation =
+                  SharedRuntime::look_for_reserved_stack_annotated_method(thread, fr);
+                if (activation.sp() != NULL) {
+                  thread->disable_stack_reserved_zone();
+                  if (activation.is_interpreted_frame()) {
+                    thread->set_reserved_stack_activation((address)activation.fp());
+                  } else {
+                    thread->set_reserved_stack_activation((address)activation.unextended_sp());
+                  }
+                  return 1;
+                }
+              }
+            }
             // Throw a stack overflow exception.
             // Guard pages will be reenabled while unwinding the stack.
+            thread->disable_stack_yellow_reserved_zone();
             stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW);
           } else {
             // Thread was in the vm or native code. Return and try to finish.
+            thread->disable_stack_yellow_reserved_zone();
             return 1;
           }
         } else if (thread->in_stack_red_zone(addr)) {
--- a/hotspot/test/runtime/ReservedStack/ReservedStackTest.java	Thu Jun 02 09:44:41 2016 +0200
+++ b/hotspot/test/runtime/ReservedStack/ReservedStackTest.java	Fri May 13 15:22:48 2016 +0200
@@ -27,6 +27,7 @@
  * @modules java.base/jdk.internal.misc
  * @modules java.base/jdk.internal.vm.annotation
  * @build jdk.test.lib.*
+ * @run main/othervm -Xint ReservedStackTest
  * @run main/othervm -XX:-Inline -XX:CompileCommand=exclude,java/util/concurrent/locks/AbstractOwnableSynchronizer.setExclusiveOwnerThread ReservedStackTest
  */
 
@@ -196,9 +197,12 @@
             System.out.println("Test started execution at frame = " + (counter - deframe));
             String result = test.getResult();
             // The feature is not fully implemented on all platforms,
-            // corruptions are still possible
-            boolean supportedPlatform = Platform.isSolaris() || Platform.isOSX()
-                || (Platform.isLinux() && (Platform.isX86() || Platform.isX64()));
+            // corruptions are still possible.
+            boolean supportedPlatform =
+                Platform.isAix() ||
+                (Platform.isLinux() && (Platform.isPPC() || Platform.isX64() || Platform.isX86())) ||
+                Platform.isOSX() ||
+                Platform.isSolaris();
             if (supportedPlatform && !result.contains("PASSED")) {
                 System.out.println(result);
                 throw new Error(result);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/ReservedStack/ReservedStackTestCompiler.java	Fri May 13 15:22:48 2016 +0200
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test ReservedStackTestCompiler
+ * @summary Run ReservedStackTest with dedicated compilers C1 and C2.
+ * @requires vm.flavor == "server"
+ * @library /testlibrary
+ * @modules java.base/jdk.internal.misc
+ * @modules java.base/jdk.internal.vm.annotation
+ * @build jdk.test.lib.* ReservedStackTest
+ * @run main/othervm -XX:+TieredCompilation -XX:TieredStopAtLevel=1 -XX:-Inline -XX:CompileCommand=exclude,java/util/concurrent/locks/AbstractOwnableSynchronizer.setExclusiveOwnerThread ReservedStackTest
+ * @run main/othervm -XX:-TieredCompilation                         -XX:-Inline -XX:CompileCommand=exclude,java/util/concurrent/locks/AbstractOwnableSynchronizer.setExclusiveOwnerThread ReservedStackTest
+ */
+
+// Intentionally left blank. Just runs ReservedStackTest with @requires annotation.