1*795d594fSAndroid Build Coastguard Worker /* Copyright (C) 2017 The Android Open Source Project 2*795d594fSAndroid Build Coastguard Worker * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3*795d594fSAndroid Build Coastguard Worker * 4*795d594fSAndroid Build Coastguard Worker * This file implements interfaces from the file jvmti.h. This implementation 5*795d594fSAndroid Build Coastguard Worker * is licensed under the same terms as the file jvmti.h. The 6*795d594fSAndroid Build Coastguard Worker * copyright and license information for the file jvmti.h follows. 7*795d594fSAndroid Build Coastguard Worker * 8*795d594fSAndroid Build Coastguard Worker * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. 9*795d594fSAndroid Build Coastguard Worker * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 10*795d594fSAndroid Build Coastguard Worker * 11*795d594fSAndroid Build Coastguard Worker * This code is free software; you can redistribute it and/or modify it 12*795d594fSAndroid Build Coastguard Worker * under the terms of the GNU General Public License version 2 only, as 13*795d594fSAndroid Build Coastguard Worker * published by the Free Software Foundation. Oracle designates this 14*795d594fSAndroid Build Coastguard Worker * particular file as subject to the "Classpath" exception as provided 15*795d594fSAndroid Build Coastguard Worker * by Oracle in the LICENSE file that accompanied this code. 16*795d594fSAndroid Build Coastguard Worker * 17*795d594fSAndroid Build Coastguard Worker * This code is distributed in the hope that it will be useful, but WITHOUT 18*795d594fSAndroid Build Coastguard Worker * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 19*795d594fSAndroid Build Coastguard Worker * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 20*795d594fSAndroid Build Coastguard Worker * version 2 for more details (a copy is included in the LICENSE file that 21*795d594fSAndroid Build Coastguard Worker * accompanied this code). 22*795d594fSAndroid Build Coastguard Worker * 23*795d594fSAndroid Build Coastguard Worker * You should have received a copy of the GNU General Public License version 24*795d594fSAndroid Build Coastguard Worker * 2 along with this work; if not, write to the Free Software Foundation, 25*795d594fSAndroid Build Coastguard Worker * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 26*795d594fSAndroid Build Coastguard Worker * 27*795d594fSAndroid Build Coastguard Worker * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 28*795d594fSAndroid Build Coastguard Worker * or visit www.oracle.com if you need additional information or have any 29*795d594fSAndroid Build Coastguard Worker * questions. 30*795d594fSAndroid Build Coastguard Worker */ 31*795d594fSAndroid Build Coastguard Worker 32*795d594fSAndroid Build Coastguard Worker #ifndef ART_OPENJDKJVMTI_DEOPT_MANAGER_H_ 33*795d594fSAndroid Build Coastguard Worker #define ART_OPENJDKJVMTI_DEOPT_MANAGER_H_ 34*795d594fSAndroid Build Coastguard Worker 35*795d594fSAndroid Build Coastguard Worker #include <atomic> 36*795d594fSAndroid Build Coastguard Worker #include <iosfwd> 37*795d594fSAndroid Build Coastguard Worker #include <unordered_map> 38*795d594fSAndroid Build Coastguard Worker 39*795d594fSAndroid Build Coastguard Worker #include "base/mutex.h" 40*795d594fSAndroid Build Coastguard Worker #include "runtime_callbacks.h" 41*795d594fSAndroid Build Coastguard Worker 42*795d594fSAndroid Build Coastguard Worker #include <jvmti.h> 43*795d594fSAndroid Build Coastguard Worker 44*795d594fSAndroid Build Coastguard Worker namespace art { 45*795d594fSAndroid Build Coastguard Worker class ArtMethod; 46*795d594fSAndroid Build Coastguard Worker class ScopedObjectAccessUnchecked; 47*795d594fSAndroid Build Coastguard Worker namespace mirror { 48*795d594fSAndroid Build Coastguard Worker class Class; 49*795d594fSAndroid Build Coastguard Worker } // namespace mirror 50*795d594fSAndroid Build Coastguard Worker } // namespace art 51*795d594fSAndroid Build Coastguard Worker 52*795d594fSAndroid Build Coastguard Worker namespace openjdkjvmti { 53*795d594fSAndroid Build Coastguard Worker 54*795d594fSAndroid Build Coastguard Worker class DeoptManager; 55*795d594fSAndroid Build Coastguard Worker 56*795d594fSAndroid Build Coastguard Worker struct JvmtiMethodInspectionCallback : public art::MethodInspectionCallback { 57*795d594fSAndroid Build Coastguard Worker public: JvmtiMethodInspectionCallbackJvmtiMethodInspectionCallback58*795d594fSAndroid Build Coastguard Worker explicit JvmtiMethodInspectionCallback(DeoptManager* manager) : manager_(manager) {} 59*795d594fSAndroid Build Coastguard Worker 60*795d594fSAndroid Build Coastguard Worker bool HaveLocalsChanged() override REQUIRES_SHARED(art::Locks::mutator_lock_); 61*795d594fSAndroid Build Coastguard Worker 62*795d594fSAndroid Build Coastguard Worker private: 63*795d594fSAndroid Build Coastguard Worker DeoptManager* manager_; 64*795d594fSAndroid Build Coastguard Worker }; 65*795d594fSAndroid Build Coastguard Worker 66*795d594fSAndroid Build Coastguard Worker class ScopedDeoptimizationContext; 67*795d594fSAndroid Build Coastguard Worker 68*795d594fSAndroid Build Coastguard Worker class DeoptManager { 69*795d594fSAndroid Build Coastguard Worker public: 70*795d594fSAndroid Build Coastguard Worker DeoptManager(); 71*795d594fSAndroid Build Coastguard Worker 72*795d594fSAndroid Build Coastguard Worker void Setup(); 73*795d594fSAndroid Build Coastguard Worker void Shutdown(); 74*795d594fSAndroid Build Coastguard Worker 75*795d594fSAndroid Build Coastguard Worker void DumpDeoptInfo(art::Thread* self, std::ostream& stream); 76*795d594fSAndroid Build Coastguard Worker 77*795d594fSAndroid Build Coastguard Worker void RemoveDeoptimizationRequester() REQUIRES(!deoptimization_status_lock_, 78*795d594fSAndroid Build Coastguard Worker !art::Roles::uninterruptible_); 79*795d594fSAndroid Build Coastguard Worker void AddDeoptimizationRequester() REQUIRES(!deoptimization_status_lock_, 80*795d594fSAndroid Build Coastguard Worker !art::Roles::uninterruptible_); 81*795d594fSAndroid Build Coastguard Worker bool MethodHasBreakpoints(art::ArtMethod* method) 82*795d594fSAndroid Build Coastguard Worker REQUIRES(!deoptimization_status_lock_); 83*795d594fSAndroid Build Coastguard Worker 84*795d594fSAndroid Build Coastguard Worker void RemoveMethodBreakpoint(art::ArtMethod* method) 85*795d594fSAndroid Build Coastguard Worker REQUIRES(!deoptimization_status_lock_, !art::Roles::uninterruptible_) 86*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(art::Locks::mutator_lock_); 87*795d594fSAndroid Build Coastguard Worker 88*795d594fSAndroid Build Coastguard Worker void AddMethodBreakpoint(art::ArtMethod* method) 89*795d594fSAndroid Build Coastguard Worker REQUIRES(!deoptimization_status_lock_, !art::Roles::uninterruptible_) 90*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(art::Locks::mutator_lock_); 91*795d594fSAndroid Build Coastguard Worker 92*795d594fSAndroid Build Coastguard Worker void AddDeoptimizeAllMethods() 93*795d594fSAndroid Build Coastguard Worker REQUIRES(!deoptimization_status_lock_, !art::Roles::uninterruptible_) 94*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(art::Locks::mutator_lock_); 95*795d594fSAndroid Build Coastguard Worker 96*795d594fSAndroid Build Coastguard Worker void RemoveDeoptimizeAllMethods() 97*795d594fSAndroid Build Coastguard Worker REQUIRES(!deoptimization_status_lock_, !art::Roles::uninterruptible_) 98*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(art::Locks::mutator_lock_); 99*795d594fSAndroid Build Coastguard Worker 100*795d594fSAndroid Build Coastguard Worker jvmtiError AddDeoptimizeThreadMethods(art::ScopedObjectAccessUnchecked& soa, jthread thread) 101*795d594fSAndroid Build Coastguard Worker REQUIRES(!deoptimization_status_lock_, !art::Roles::uninterruptible_) 102*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(art::Locks::mutator_lock_); 103*795d594fSAndroid Build Coastguard Worker 104*795d594fSAndroid Build Coastguard Worker jvmtiError RemoveDeoptimizeThreadMethods(art::ScopedObjectAccessUnchecked& soa, jthread thread) 105*795d594fSAndroid Build Coastguard Worker REQUIRES(!deoptimization_status_lock_, !art::Roles::uninterruptible_) 106*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(art::Locks::mutator_lock_); 107*795d594fSAndroid Build Coastguard Worker 108*795d594fSAndroid Build Coastguard Worker void DeoptimizeThread(art::Thread* target) 109*795d594fSAndroid Build Coastguard Worker REQUIRES(!art::Locks::thread_list_lock_) 110*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(art::Locks::mutator_lock_); 111*795d594fSAndroid Build Coastguard Worker void DeoptimizeAllThreads() REQUIRES_SHARED(art::Locks::mutator_lock_); 112*795d594fSAndroid Build Coastguard Worker 113*795d594fSAndroid Build Coastguard Worker void FinishSetup() REQUIRES(!deoptimization_status_lock_, !art::Roles::uninterruptible_); 114*795d594fSAndroid Build Coastguard Worker 115*795d594fSAndroid Build Coastguard Worker static DeoptManager* Get(); 116*795d594fSAndroid Build Coastguard Worker HaveLocalsChanged()117*795d594fSAndroid Build Coastguard Worker bool HaveLocalsChanged() const { 118*795d594fSAndroid Build Coastguard Worker return set_local_variable_called_.load(); 119*795d594fSAndroid Build Coastguard Worker } 120*795d594fSAndroid Build Coastguard Worker SetLocalsUpdated()121*795d594fSAndroid Build Coastguard Worker void SetLocalsUpdated() { 122*795d594fSAndroid Build Coastguard Worker set_local_variable_called_.store(true); 123*795d594fSAndroid Build Coastguard Worker } 124*795d594fSAndroid Build Coastguard Worker 125*795d594fSAndroid Build Coastguard Worker private: 126*795d594fSAndroid Build Coastguard Worker bool MethodHasBreakpointsLocked(art::ArtMethod* method) 127*795d594fSAndroid Build Coastguard Worker REQUIRES(breakpoint_status_lock_); 128*795d594fSAndroid Build Coastguard Worker 129*795d594fSAndroid Build Coastguard Worker // Wait until nothing is currently in the middle of deoptimizing/undeoptimizing something. This is 130*795d594fSAndroid Build Coastguard Worker // needed to ensure that everything is synchronized since threads need to drop the 131*795d594fSAndroid Build Coastguard Worker // deoptimization_status_lock_ while deoptimizing methods. 132*795d594fSAndroid Build Coastguard Worker void WaitForDeoptimizationToFinish(art::Thread* self) 133*795d594fSAndroid Build Coastguard Worker RELEASE(deoptimization_status_lock_) REQUIRES(!art::Locks::mutator_lock_); 134*795d594fSAndroid Build Coastguard Worker 135*795d594fSAndroid Build Coastguard Worker void WaitForDeoptimizationToFinishLocked(art::Thread* self) 136*795d594fSAndroid Build Coastguard Worker REQUIRES(deoptimization_status_lock_, !art::Locks::mutator_lock_); 137*795d594fSAndroid Build Coastguard Worker 138*795d594fSAndroid Build Coastguard Worker void AddDeoptimizeAllMethodsLocked(art::Thread* self) 139*795d594fSAndroid Build Coastguard Worker RELEASE(deoptimization_status_lock_) 140*795d594fSAndroid Build Coastguard Worker REQUIRES(!art::Roles::uninterruptible_, !art::Locks::mutator_lock_); 141*795d594fSAndroid Build Coastguard Worker 142*795d594fSAndroid Build Coastguard Worker void RemoveDeoptimizeAllMethodsLocked(art::Thread* self) 143*795d594fSAndroid Build Coastguard Worker RELEASE(deoptimization_status_lock_) 144*795d594fSAndroid Build Coastguard Worker REQUIRES(!art::Roles::uninterruptible_, !art::Locks::mutator_lock_); 145*795d594fSAndroid Build Coastguard Worker 146*795d594fSAndroid Build Coastguard Worker void PerformGlobalDeoptimization(art::Thread* self) 147*795d594fSAndroid Build Coastguard Worker RELEASE(deoptimization_status_lock_) 148*795d594fSAndroid Build Coastguard Worker REQUIRES(!art::Roles::uninterruptible_, !art::Locks::mutator_lock_); 149*795d594fSAndroid Build Coastguard Worker 150*795d594fSAndroid Build Coastguard Worker void PerformGlobalUndeoptimization(art::Thread* self) 151*795d594fSAndroid Build Coastguard Worker RELEASE(deoptimization_status_lock_) 152*795d594fSAndroid Build Coastguard Worker REQUIRES(!art::Roles::uninterruptible_, !art::Locks::mutator_lock_); 153*795d594fSAndroid Build Coastguard Worker 154*795d594fSAndroid Build Coastguard Worker void PerformLimitedDeoptimization(art::Thread* self, art::ArtMethod* method) 155*795d594fSAndroid Build Coastguard Worker RELEASE(deoptimization_status_lock_) 156*795d594fSAndroid Build Coastguard Worker REQUIRES(!art::Roles::uninterruptible_, !art::Locks::mutator_lock_); 157*795d594fSAndroid Build Coastguard Worker 158*795d594fSAndroid Build Coastguard Worker void PerformLimitedUndeoptimization(art::Thread* self, art::ArtMethod* method) 159*795d594fSAndroid Build Coastguard Worker RELEASE(deoptimization_status_lock_) 160*795d594fSAndroid Build Coastguard Worker REQUIRES(!art::Roles::uninterruptible_, !art::Locks::mutator_lock_); 161*795d594fSAndroid Build Coastguard Worker 162*795d594fSAndroid Build Coastguard Worker static constexpr const char* kDeoptManagerInstrumentationKey = "JVMTI_DeoptManager"; 163*795d594fSAndroid Build Coastguard Worker 164*795d594fSAndroid Build Coastguard Worker art::Mutex deoptimization_status_lock_ ACQUIRED_BEFORE(art::Locks::classlinker_classes_lock_); 165*795d594fSAndroid Build Coastguard Worker art::ConditionVariable deoptimization_condition_ GUARDED_BY(deoptimization_status_lock_); 166*795d594fSAndroid Build Coastguard Worker bool performing_deoptimization_ GUARDED_BY(deoptimization_status_lock_); 167*795d594fSAndroid Build Coastguard Worker 168*795d594fSAndroid Build Coastguard Worker // Number of times we have gotten requests to deopt everything. 169*795d594fSAndroid Build Coastguard Worker uint32_t global_deopt_count_ GUARDED_BY(deoptimization_status_lock_); 170*795d594fSAndroid Build Coastguard Worker 171*795d594fSAndroid Build Coastguard Worker // Number of users of deoptimization there currently are. 172*795d594fSAndroid Build Coastguard Worker uint32_t deopter_count_ GUARDED_BY(deoptimization_status_lock_); 173*795d594fSAndroid Build Coastguard Worker 174*795d594fSAndroid Build Coastguard Worker // A mutex that just protects the breakpoint-status map. This mutex should always be at the 175*795d594fSAndroid Build Coastguard Worker // bottom of the lock hierarchy. Nothing more should be locked if we hold this. 176*795d594fSAndroid Build Coastguard Worker art::Mutex breakpoint_status_lock_ ACQUIRED_BEFORE(art::Locks::abort_lock_); 177*795d594fSAndroid Build Coastguard Worker // A map from methods to the number of breakpoints in them from all envs. 178*795d594fSAndroid Build Coastguard Worker std::unordered_map<art::ArtMethod*, uint32_t> breakpoint_status_ 179*795d594fSAndroid Build Coastguard Worker GUARDED_BY(breakpoint_status_lock_); 180*795d594fSAndroid Build Coastguard Worker 181*795d594fSAndroid Build Coastguard Worker // The MethodInspectionCallback we use to tell the runtime if we care about particular methods. 182*795d594fSAndroid Build Coastguard Worker JvmtiMethodInspectionCallback inspection_callback_; 183*795d594fSAndroid Build Coastguard Worker 184*795d594fSAndroid Build Coastguard Worker // Set to true if anything calls SetLocalVariables on any thread since we need to be careful about 185*795d594fSAndroid Build Coastguard Worker // OSR after this. 186*795d594fSAndroid Build Coastguard Worker std::atomic<bool> set_local_variable_called_; 187*795d594fSAndroid Build Coastguard Worker 188*795d594fSAndroid Build Coastguard Worker // Helper for setting up/tearing-down for deoptimization. 189*795d594fSAndroid Build Coastguard Worker friend class ScopedDeoptimizationContext; 190*795d594fSAndroid Build Coastguard Worker }; 191*795d594fSAndroid Build Coastguard Worker 192*795d594fSAndroid Build Coastguard Worker } // namespace openjdkjvmti 193*795d594fSAndroid Build Coastguard Worker #endif // ART_OPENJDKJVMTI_DEOPT_MANAGER_H_ 194