1 /* 2 * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved. 3 * Copyright (c) 2020 SAP SE. All rights reserved. 4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5 * 6 * This code is free software; you can redistribute it and/or modify it 7 * under the terms of the GNU General Public License version 2 only, as 8 * published by the Free Software Foundation. 9 * 10 * This code is distributed in the hope that it will be useful, but WITHOUT 11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 * version 2 for more details (a copy is included in the LICENSE file that 14 * accompanied this code). 15 * 16 * You should have received a copy of the GNU General Public License version 17 * 2 along with this work; if not, write to the Free Software Foundation, 18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 * 20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 21 * or visit www.oracle.com if you need additional information or have any 22 * questions. 23 * 24 */ 25 26 #ifndef SHARE_RUNTIME_ESCAPEBARRIER_HPP 27 #define SHARE_RUNTIME_ESCAPEBARRIER_HPP 28 29 #include "memory/allocation.hpp" 30 #include "runtime/globals.hpp" 31 #include "utilities/macros.hpp" 32 33 class JavaThread; 34 35 // EscapeBarriers should be put on execution paths where JVMTI agents can access object 36 // references held by java threads. 37 // They provide means to revert optimizations based on escape analysis in a well synchronized manner 38 // just before local references escape through JVMTI. 39 40 class EscapeBarrier : StackObj { 41 42 #if COMPILER2_OR_JVMCI 43 JavaThread* const _calling_thread; 44 JavaThread* const _deoptee_thread; 45 bool const _barrier_active; 46 47 static bool _deoptimizing_objects_for_all_threads; 48 static bool _self_deoptimization_in_progress; 49 50 // Suspending is necessary because the target thread's stack must be walked and 51 // object reallocation is not possible in a handshake or at a safepoint. 52 // Suspending is based on handshakes. It is sufficient if the target thread(s) 53 // cannot return to executing bytecodes. Acquiring a lock is ok. Leaving a 54 // safepoint/handshake safe state is not ok. 55 // See also JavaThread::wait_for_object_deoptimization(). 56 void sync_and_suspend_one(); 57 void sync_and_suspend_all(); 58 void resume_one(); 59 void resume_all(); 60 61 // Deoptimize the given frame and deoptimize objects with optimizations based on escape analysis. 62 bool deoptimize_objects_internal(JavaThread* deoptee, intptr_t* fr_id); 63 64 // Deoptimize objects, i.e. reallocate and relock them. The target frames are deoptimized. 65 // The methods return false iff at least one reallocation failed. deoptimize_objects(intptr_t * fr_id)66 bool deoptimize_objects(intptr_t* fr_id) { 67 return deoptimize_objects_internal(deoptee_thread(), fr_id); 68 } 69 70 public: 71 // Revert ea based optimizations for given deoptee thread EscapeBarrier(bool barrier_active,JavaThread * calling_thread,JavaThread * deoptee_thread)72 EscapeBarrier(bool barrier_active, JavaThread* calling_thread, JavaThread* deoptee_thread) 73 : _calling_thread(calling_thread), _deoptee_thread(deoptee_thread), 74 _barrier_active(barrier_active && (JVMCI_ONLY(UseJVMCICompiler) NOT_JVMCI(false) 75 COMPILER2_PRESENT(|| DoEscapeAnalysis))) 76 { 77 if (_barrier_active) sync_and_suspend_one(); 78 } 79 80 // Revert ea based optimizations for all java threads EscapeBarrier(bool barrier_active,JavaThread * calling_thread)81 EscapeBarrier(bool barrier_active, JavaThread* calling_thread) 82 : _calling_thread(calling_thread), _deoptee_thread(NULL), 83 _barrier_active(barrier_active && (JVMCI_ONLY(UseJVMCICompiler) NOT_JVMCI(false) 84 COMPILER2_PRESENT(|| DoEscapeAnalysis))) 85 { 86 if (_barrier_active) sync_and_suspend_all(); 87 } 88 89 #else 90 91 public: 92 EscapeBarrier(bool barrier_active, JavaThread* calling_thread, JavaThread* deoptee_thread) { } 93 EscapeBarrier(bool barrier_active, JavaThread* calling_thread) { } 94 static bool deoptimizing_objects_for_all_threads() { return false; } 95 bool barrier_active() const { return false; } 96 #endif // COMPILER2_OR_JVMCI 97 98 // Deoptimize objects of frames of the target thread up to the given depth. 99 // Deoptimize objects of caller frames if they passed references to ArgEscape objects as arguments. 100 // Return false in the case of a reallocation failure and true otherwise. deoptimize_objects(int depth)101 bool deoptimize_objects(int depth) { 102 return deoptimize_objects(0, depth); 103 } 104 105 // Deoptimize objects of frames of the target thread at depth >= d1 and depth <= d2. 106 // Deoptimize objects of caller frames if they passed references to ArgEscape objects as arguments. 107 // Return false in the case of a reallocation failure and true otherwise. 108 bool deoptimize_objects(int d1, int d2) NOT_COMPILER2_OR_JVMCI_RETURN_(true); 109 110 // Find and deoptimize non escaping objects and the holding frames on all stacks. 111 bool deoptimize_objects_all_threads() NOT_COMPILER2_OR_JVMCI_RETURN_(true); 112 113 // A java thread was added to the list of threads. 114 static void thread_added(JavaThread* jt) NOT_COMPILER2_OR_JVMCI_RETURN; 115 116 // A java thread was removed from the list of threads. 117 static void thread_removed(JavaThread* jt) NOT_COMPILER2_OR_JVMCI_RETURN; 118 119 #if COMPILER2_OR_JVMCI 120 // Returns true iff objects were reallocated and relocked because of access through JVMTI. 121 static bool objs_are_deoptimized(JavaThread* thread, intptr_t* fr_id); 122 deoptimizing_objects_for_all_threads()123 static bool deoptimizing_objects_for_all_threads() { return _deoptimizing_objects_for_all_threads; } 124 ~EscapeBarrier()125 ~EscapeBarrier() { 126 if (!barrier_active()) return; 127 if (all_threads()) { 128 resume_all(); 129 } else { 130 resume_one(); 131 } 132 } 133 134 // Should revert optimizations for all threads. all_threads() const135 bool all_threads() const { return _deoptee_thread == NULL; } 136 137 // Current thread deoptimizes its own objects. self_deopt() const138 bool self_deopt() const { return _calling_thread == _deoptee_thread; } 139 140 // Inactive barriers are created if no local objects can escape. barrier_active() const141 bool barrier_active() const { return _barrier_active; } 142 143 // accessors calling_thread() const144 JavaThread* calling_thread() const { return _calling_thread; } deoptee_thread() const145 JavaThread* deoptee_thread() const { return _deoptee_thread; } 146 #endif // COMPILER2_OR_JVMCI 147 }; 148 149 #endif // SHARE_RUNTIME_ESCAPEBARRIER_HPP 150