--- old/src/share/vm/opto/runtime.cpp 2016-12-03 12:35:40.922570640 +0300 +++ new/src/share/vm/opto/runtime.cpp 2016-12-03 12:35:40.826570642 +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); --- old/src/share/vm/prims/jvmtiExport.cpp 2016-12-03 12:35:41.259570634 +0300 +++ new/src/share/vm/prims/jvmtiExport.cpp 2016-12-03 12:35:41.174570635 +0300 @@ -130,8 +130,7 @@ private: JavaThread *_thread; JNIEnv* _jni_env; - bool _exception_detected; - bool _exception_caught; + JvmtiThreadState::ExceptionState _exception_state; #if 0 JNIHandleBlock* _hblock; #endif @@ -149,11 +148,11 @@ // 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; + state->save_exception_state(&_exception_state); + } + else { + // For safety ... + _exception_state = JvmtiThreadState::ES_CLEARED; } JNIHandleBlock* old_handles = thread->active_handles(); @@ -186,12 +185,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(_exception_state); } } @@ -1387,7 +1381,6 @@ } } - void JvmtiExport::post_exception_throw(JavaThread *thread, Method* method, address location, oop exception) { HandleMark hm(thread); methodHandle mh(thread, method); @@ -2289,7 +2282,7 @@ JvmtiThreadState* state = thread->jvmti_thread_state(); if (state != NULL) { - state->clear_exception_detected(); + state->clear_exception_state(); } } --- old/src/share/vm/prims/jvmtiThreadState.cpp 2016-12-03 12:35:41.579570627 +0300 +++ new/src/share/vm/prims/jvmtiThreadState.cpp 2016-12-03 12:35:41.496570629 +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 --- old/src/share/vm/prims/jvmtiThreadState.hpp 2016-12-03 12:35:41.886570621 +0300 +++ new/src/share/vm/prims/jvmtiThreadState.hpp 2016-12-03 12:35:41.801570622 +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 void save_exception_state(ExceptionState *state) { *state = _exception_state; } + inline void restore_exception_state(ExceptionState state) { _exception_state = state; } inline void clear_hide_single_stepping() { if (_hide_level > 0) { --- old/test/serviceability/jvmti/ExceptionCaughtOutOfPhase/ExceptionCaughtOutOfPhaseTest.java 2016-12-03 12:35:42.178570615 +0300 +++ /dev/null 2016-12-02 02:27:34.281244877 +0300 @@ -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(); - } - } -}