8165496: assert(_exception_caught == false) failed: _exception_caught is out of phase
authordsamersoff
Tue, 20 Dec 2016 15:40:01 +0300
changeset 42895 c97cd79636ec
parent 42891 2104a8acb194
child 42896 c868a2f327c6
8165496: assert(_exception_caught == false) failed: _exception_caught is out of phase Summary: Two separate flags, exception_detected and exception_caught, replaced with one. Reviewed-by: sspitsyn, coleenp, dholmes
hotspot/src/share/vm/opto/runtime.cpp
hotspot/src/share/vm/prims/jvmtiExport.cpp
hotspot/src/share/vm/prims/jvmtiThreadState.cpp
hotspot/src/share/vm/prims/jvmtiThreadState.hpp
hotspot/test/serviceability/jvmti/ExceptionCaughtOutOfPhase/ExceptionCaughtOutOfPhaseTest.java
--- a/hotspot/src/share/vm/opto/runtime.cpp	Tue Dec 20 11:32:47 2016 +0000
+++ b/hotspot/src/share/vm/opto/runtime.cpp	Tue Dec 20 15:40:01 2016 +0300
@@ -59,7 +59,6 @@
 #include "opto/mulnode.hpp"
 #include "opto/runtime.hpp"
 #include "opto/subnode.hpp"
-#include "prims/jvmtiThreadState.hpp"
 #include "runtime/atomic.hpp"
 #include "runtime/fprofiler.hpp"
 #include "runtime/handles.inline.hpp"
@@ -1458,11 +1457,6 @@
   }
 #endif
 
-  JvmtiThreadState *state = thread->jvmti_thread_state();
-  if (state != NULL) {
-    state->set_exception_detected();
-  }
-
   thread->set_vm_result(exception);
   // Frame not compiled (handles deoptimization blob)
   return SharedRuntime::raw_exception_handler_for_return_address(thread, ret_pc);
--- a/hotspot/src/share/vm/prims/jvmtiExport.cpp	Tue Dec 20 11:32:47 2016 +0000
+++ b/hotspot/src/share/vm/prims/jvmtiExport.cpp	Tue Dec 20 15:40:01 2016 +0300
@@ -130,15 +130,15 @@
 private:
   JavaThread *_thread;
   JNIEnv* _jni_env;
-  bool _exception_detected;
-  bool _exception_caught;
+  JvmtiThreadState::ExceptionState _saved_exception_state;
 #if 0
   JNIHandleBlock* _hblock;
 #endif
 
 public:
   JvmtiEventMark(JavaThread *thread) :  _thread(thread),
-                                         _jni_env(thread->jni_environment()) {
+                                        _jni_env(thread->jni_environment()),
+                                        _saved_exception_state(JvmtiThreadState::ES_CLEARED) {
 #if 0
     _hblock = thread->active_handles();
     _hblock->clear_thoroughly(); // so we can be safe
@@ -149,11 +149,7 @@
     // we are before an event.
     // Save current jvmti thread exception state.
     if (state != NULL) {
-      _exception_detected = state->is_exception_detected();
-      _exception_caught = state->is_exception_caught();
-    } else {
-      _exception_detected = false;
-      _exception_caught = false;
+      _saved_exception_state = state->get_exception_state();
     }
 
     JNIHandleBlock* old_handles = thread->active_handles();
@@ -186,12 +182,7 @@
     // we are continuing after an event.
     if (state != NULL) {
       // Restore the jvmti thread exception state.
-      if (_exception_detected) {
-        state->set_exception_detected();
-      }
-      if (_exception_caught) {
-        state->set_exception_caught();
-      }
+      state->restore_exception_state(_saved_exception_state);
     }
   }
 
@@ -1552,7 +1543,6 @@
   }
 }
 
-
 void JvmtiExport::post_exception_throw(JavaThread *thread, Method* method, address location, oop exception) {
   HandleMark hm(thread);
   methodHandle mh(thread, method);
@@ -2454,7 +2444,7 @@
 
   JvmtiThreadState* state = thread->jvmti_thread_state();
   if (state != NULL) {
-    state->clear_exception_detected();
+    state->clear_exception_state();
   }
 }
 
--- a/hotspot/src/share/vm/prims/jvmtiThreadState.cpp	Tue Dec 20 11:32:47 2016 +0000
+++ b/hotspot/src/share/vm/prims/jvmtiThreadState.cpp	Tue Dec 20 15:40:01 2016 +0300
@@ -50,8 +50,7 @@
   : _thread_event_enable() {
   assert(JvmtiThreadState_lock->is_locked(), "sanity check");
   _thread               = thread;
-  _exception_detected   = false;
-  _exception_caught     = false;
+  _exception_state      = ES_CLEARED;
   _debuggable           = true;
   _hide_single_stepping = false;
   _hide_level           = 0;
@@ -310,7 +309,7 @@
   // an exception.
   //
   if (is_exception_detected()) {
-    clear_exception_detected();
+    clear_exception_state();
   }
   // If step is pending for popframe then it may not be
   // a repeat step. The new_bci and method_id is same as current_bci
@@ -385,7 +384,7 @@
   // an exception.
   //
   if (is_exception_detected()) {
-    clear_exception_detected();
+    clear_exception_state();
   }
   // If step is pending for earlyret then it may not be a repeat step.
   // The new_bci and method_id is same as current_bci and current
--- a/hotspot/src/share/vm/prims/jvmtiThreadState.hpp	Tue Dec 20 11:32:47 2016 +0000
+++ b/hotspot/src/share/vm/prims/jvmtiThreadState.hpp	Tue Dec 20 15:40:01 2016 +0300
@@ -76,13 +76,21 @@
  private:
   friend class JvmtiEnv;
   JavaThread        *_thread;
-  bool              _exception_detected;
-  bool              _exception_caught;
   bool              _hide_single_stepping;
   bool              _pending_step_for_popframe;
   bool              _pending_step_for_earlyret;
   int               _hide_level;
 
+ public:
+  enum ExceptionState {
+    ES_CLEARED,
+    ES_DETECTED,
+    ES_CAUGHT
+  };
+
+ private:
+  ExceptionState _exception_state;
+
   // Used to send class being redefined/retransformed and kind of transform
   // info to the class file load hook event handler.
   KlassHandle           *_class_being_redefined;
@@ -161,16 +169,18 @@
   int count_frames();
 
   inline JavaThread *get_thread()      { return _thread;              }
-  inline bool is_exception_detected()  { return _exception_detected;  }
-  inline bool is_exception_caught()    { return _exception_caught;  }
-  inline void set_exception_detected() { _exception_detected = true;
-                                         _exception_caught = false; }
-  inline void clear_exception_detected() {
-    _exception_detected = false;
-    assert(_exception_caught == false, "_exception_caught is out of phase");
-  }
-  inline void set_exception_caught()   { _exception_caught = true;
-                                         _exception_detected = false; }
+
+  inline bool is_exception_detected()  { return _exception_state == ES_DETECTED;  }
+  inline bool is_exception_caught()    { return _exception_state == ES_CAUGHT;  }
+
+  inline void set_exception_detected() { _exception_state = ES_DETECTED; }
+  inline void set_exception_caught()   { _exception_state = ES_CAUGHT; }
+
+  inline void clear_exception_state() { _exception_state = ES_CLEARED; }
+
+  // We need to save and restore exception state inside JvmtiEventMark
+  inline ExceptionState get_exception_state() { return _exception_state; }
+  inline void restore_exception_state(ExceptionState state) { _exception_state = state; }
 
   inline void clear_hide_single_stepping() {
     if (_hide_level > 0) {
--- a/hotspot/test/serviceability/jvmti/ExceptionCaughtOutOfPhase/ExceptionCaughtOutOfPhaseTest.java	Tue Dec 20 11:32:47 2016 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,61 +0,0 @@
-/*
- * 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.
- */
-
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-
-/*
- * @test
- * @bug 8134434
- * @summary JVM_DoPrivileged() fires assert(_exception_caught == false) failed: _exception_caught is out of phase
- * @run main/othervm -agentlib:jdwp=transport=dt_socket,address=9000,server=y,suspend=n -Xbatch ExceptionCaughtOutOfPhaseTest
- */
-
-public class ExceptionCaughtOutOfPhaseTest {
-    public static void main(String[] args) {
-        PrivilegedAction action = new HotThrowingAction();
-        System.out.println("### Warm-up");
-        for(int i=0; i<11000; i++) {
-            try {
-                action.run(); // call run() to get it compiled
-            } catch(Throwable t) {
-                // ignored
-            }
-        }
-
-        System.out.println("### Warm-up done");
-        System.out.println("### Executing privileged action");
-
-        try {
-            AccessController.doPrivileged(action);
-        } catch (Error e) {
-            // ignored
-        }
-    }
-
-    public static class HotThrowingAction implements PrivilegedAction {
-        public Object run() {
-            throw new Error();
-        }
-    }
-}