8172791: Issues with JEP 270 (ReservedStackArea)
authorfparain
Fri, 11 Aug 2017 16:29:00 -0400
changeset 46796 ec791efbdecf
parent 46795 623a5e42deb6
child 46799 d8a818513b8c
child 46802 cf78889c7590
child 46804 db2cd95b294c
8172791: Issues with JEP 270 (ReservedStackArea) Reviewed-by: dcubed, thartmann Contributed-by: aph@redhat.com
hotspot/src/cpu/x86/vm/interp_masm_x86.cpp
hotspot/src/share/vm/code/compiledMethod.cpp
hotspot/src/share/vm/code/compiledMethod.hpp
hotspot/src/share/vm/opto/compile.cpp
hotspot/src/share/vm/runtime/sharedRuntime.cpp
hotspot/test/runtime/ReservedStack/ReservedStackTest.java
--- a/hotspot/src/cpu/x86/vm/interp_masm_x86.cpp	Thu Aug 10 18:09:19 2017 -0700
+++ b/hotspot/src/cpu/x86/vm/interp_masm_x86.cpp	Fri Aug 11 16:29:00 2017 -0400
@@ -1089,7 +1089,6 @@
 
     call_VM_leaf(
       CAST_FROM_FN_PTR(address, SharedRuntime::enable_stack_reserved_zone), rthread);
-    push(rthread);
     call_VM(noreg, CAST_FROM_FN_PTR(address,
                    InterpreterRuntime::throw_delayed_StackOverflowError));
     should_not_reach_here();
--- a/hotspot/src/share/vm/code/compiledMethod.cpp	Thu Aug 10 18:09:19 2017 -0700
+++ b/hotspot/src/share/vm/code/compiledMethod.cpp	Fri Aug 11 16:29:00 2017 -0400
@@ -209,6 +209,14 @@
                        pd->return_oop());
 }
 
+ScopeDesc* CompiledMethod::scope_desc_near(address pc) {
+  PcDesc* pd = pc_desc_near(pc);
+  guarantee(pd != NULL, "scope must be present");
+  return new ScopeDesc(this, pd->scope_decode_offset(),
+                       pd->obj_decode_offset(), pd->should_reexecute(), pd->rethrow_exception(),
+                       pd->return_oop());
+}
+
 void CompiledMethod::cleanup_inline_caches(bool clean_all/*=false*/) {
   assert_locked_or_safepoint(CompiledIC_lock);
 
--- a/hotspot/src/share/vm/code/compiledMethod.hpp	Thu Aug 10 18:09:19 2017 -0700
+++ b/hotspot/src/share/vm/code/compiledMethod.hpp	Fri Aug 11 16:29:00 2017 -0400
@@ -213,11 +213,12 @@
 
   // ScopeDesc retrieval operation
   PcDesc* pc_desc_at(address pc)   { return find_pc_desc(pc, false); }
-  // pc_desc_near returns the first PcDesc at or after the givne pc.
+  // pc_desc_near returns the first PcDesc at or after the given pc.
   PcDesc* pc_desc_near(address pc) { return find_pc_desc(pc, true); }
 
   // ScopeDesc for an instruction
   ScopeDesc* scope_desc_at(address pc);
+  ScopeDesc* scope_desc_near(address pc);
 
   bool is_at_poll_return(address pc);
   bool is_at_poll_or_poll_return(address pc);
--- a/hotspot/src/share/vm/opto/compile.cpp	Thu Aug 10 18:09:19 2017 -0700
+++ b/hotspot/src/share/vm/opto/compile.cpp	Fri Aug 11 16:29:00 2017 -0400
@@ -993,7 +993,8 @@
     _print_inlining_output(NULL),
     _allowed_reasons(0),
     _interpreter_frame_size(0),
-    _max_node_limit(MaxNodeLimit) {
+    _max_node_limit(MaxNodeLimit),
+    _has_reserved_stack_access(false) {
   C = this;
 
   TraceTime t1(NULL, &_t_totalCompilation, CITime, false);
--- a/hotspot/src/share/vm/runtime/sharedRuntime.cpp	Thu Aug 10 18:09:19 2017 -0700
+++ b/hotspot/src/share/vm/runtime/sharedRuntime.cpp	Fri Aug 11 16:29:00 2017 -0400
@@ -3128,11 +3128,14 @@
 
 JRT_LEAF(void, SharedRuntime::enable_stack_reserved_zone(JavaThread* thread))
   assert(thread->is_Java_thread(), "Only Java threads have a stack reserved zone");
+  if (thread->stack_reserved_zone_disabled()) {
   thread->enable_stack_reserved_zone();
+  }
   thread->set_reserved_stack_activation(thread->stack_base());
 JRT_END
 
 frame SharedRuntime::look_for_reserved_stack_annotated_method(JavaThread* thread, frame fr) {
+  ResourceMark rm(thread);
   frame activation;
   CompiledMethod* nm = NULL;
   int count = 1;
@@ -3141,17 +3144,28 @@
 
   while (true) {
     Method* method = NULL;
+    bool found = false;
     if (fr.is_interpreted_frame()) {
       method = fr.interpreter_frame_method();
+      if (method != NULL && method->has_reserved_stack_access()) {
+        found = true;
+      }
     } else {
       CodeBlob* cb = fr.cb();
       if (cb != NULL && cb->is_compiled()) {
         nm = cb->as_compiled_method();
         method = nm->method();
+        // scope_desc_near() must be used, instead of scope_desc_at() because on
+        // SPARC, the pcDesc can be on the delay slot after the call instruction.
+        for (ScopeDesc *sd = nm->scope_desc_near(fr.pc()); sd != NULL; sd = sd->sender()) {
+          method = sd->method();
+          if (method != NULL && method->has_reserved_stack_access()) {
+            found = true;
       }
     }
-    if ((method != NULL) && method->has_reserved_stack_access()) {
-      ResourceMark rm(thread);
+      }
+    }
+    if (found) {
       activation = fr;
       warning("Potentially dangerous stack overflow in "
               "ReservedStackAccess annotated method %s [%d]",
--- a/hotspot/test/runtime/ReservedStack/ReservedStackTest.java	Thu Aug 10 18:09:19 2017 -0700
+++ b/hotspot/test/runtime/ReservedStack/ReservedStackTest.java	Fri Aug 11 16:29:00 2017 -0400
@@ -26,8 +26,7 @@
  * @library /test/lib
  * @modules java.base/jdk.internal.misc
  * @modules java.base/jdk.internal.vm.annotation
- * @run main/othervm -Xint ReservedStackTest
- * @run main/othervm -XX:-Inline -XX:CompileCommand=exclude,java/util/concurrent/locks/AbstractOwnableSynchronizer.setExclusiveOwnerThread ReservedStackTest
+ * @run main/othervm -XX:MaxInlineLevel=2 -XX:CompileCommand=exclude,java/util/concurrent/locks/AbstractOwnableSynchronizer.setExclusiveOwnerThread ReservedStackTest
  */
 
 /* The exclusion of java.util.concurrent.locks.AbstractOwnableSynchronizer.setExclusiveOwnerThread()
@@ -161,6 +160,7 @@
             } catch (StackOverflowError e) {
                 soe = e;
                 stackOverflowErrorReceived = true;
+                throw e;
             }
         }
 
@@ -194,13 +194,10 @@
             decounter = deframe;
             test.initialize();
             recursiveCall();
-            System.out.println("Framework got StackOverflowError at frame = " + counter);
-            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.
             if (isSupportedPlatform && !result.contains("PASSED")) {
-                System.out.println(result);
                 throw new Error(result);
             } else {
                 // Either the test passed or this platform is not supported.
@@ -289,7 +286,7 @@
 
     public static void main(String[] args) throws Exception {
         initIsSupportedPlatform();
-        for (int i = 0; i < 1000; i++) {
+        for (int i = 0; i < 100; i++) {
             // Each iteration has to be executed by a new thread. The test
             // relies on the random size area pushed by the VM at the beginning
             // of the stack of each Java thread it creates.