diff options
Diffstat (limited to 'openjdkjvmti/deopt_manager.h')
| -rw-r--r-- | openjdkjvmti/deopt_manager.h | 168 |
1 files changed, 168 insertions, 0 deletions
diff --git a/openjdkjvmti/deopt_manager.h b/openjdkjvmti/deopt_manager.h new file mode 100644 index 0000000000..b265fa8ec2 --- /dev/null +++ b/openjdkjvmti/deopt_manager.h @@ -0,0 +1,168 @@ +/* Copyright (C) 2017 The Android Open Source Project + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This file implements interfaces from the file jvmti.h. This implementation + * is licensed under the same terms as the file jvmti.h. The + * copyright and license information for the file jvmti.h follows. + * + * Copyright (c) 2003, 2011, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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. + */ + +#ifndef ART_OPENJDKJVMTI_DEOPT_MANAGER_H_ +#define ART_OPENJDKJVMTI_DEOPT_MANAGER_H_ + +#include <unordered_map> + +#include "jni.h" +#include "jvmti.h" + +#include "base/mutex.h" +#include "runtime_callbacks.h" +#include "ti_breakpoint.h" + +namespace art { +class ArtMethod; +namespace mirror { +class Class; +} // namespace mirror +} // namespace art + +namespace openjdkjvmti { + +class DeoptManager; + +struct JvmtiMethodInspectionCallback : public art::MethodInspectionCallback { + public: + explicit JvmtiMethodInspectionCallback(DeoptManager* manager) : manager_(manager) {} + + bool IsMethodBeingInspected(art::ArtMethod* method) + OVERRIDE REQUIRES_SHARED(art::Locks::mutator_lock_); + + bool IsMethodSafeToJit(art::ArtMethod* method) + OVERRIDE REQUIRES_SHARED(art::Locks::mutator_lock_); + + private: + DeoptManager* manager_; +}; + +class ScopedDeoptimizationContext; + +class DeoptManager { + public: + DeoptManager(); + + void Setup(); + void Shutdown(); + + void RemoveDeoptimizationRequester() REQUIRES(!deoptimization_status_lock_, + !art::Roles::uninterruptible_); + void AddDeoptimizationRequester() REQUIRES(!deoptimization_status_lock_, + !art::Roles::uninterruptible_); + bool MethodHasBreakpoints(art::ArtMethod* method) + REQUIRES(!deoptimization_status_lock_); + + void RemoveMethodBreakpoint(art::ArtMethod* method) + REQUIRES(!deoptimization_status_lock_, !art::Roles::uninterruptible_) + REQUIRES_SHARED(art::Locks::mutator_lock_); + + void AddMethodBreakpoint(art::ArtMethod* method) + REQUIRES(!deoptimization_status_lock_, !art::Roles::uninterruptible_) + REQUIRES_SHARED(art::Locks::mutator_lock_); + + void AddDeoptimizeAllMethods() + REQUIRES(!deoptimization_status_lock_, !art::Roles::uninterruptible_) + REQUIRES_SHARED(art::Locks::mutator_lock_); + + void RemoveDeoptimizeAllMethods() + REQUIRES(!deoptimization_status_lock_, !art::Roles::uninterruptible_) + REQUIRES_SHARED(art::Locks::mutator_lock_); + + void DeoptimizeThread(art::Thread* target) REQUIRES_SHARED(art::Locks::mutator_lock_); + void DeoptimizeAllThreads() REQUIRES_SHARED(art::Locks::mutator_lock_); + + static DeoptManager* Get(); + + private: + bool MethodHasBreakpointsLocked(art::ArtMethod* method) + REQUIRES(deoptimization_status_lock_); + + // Wait until nothing is currently in the middle of deoptimizing/undeoptimizing something. This is + // needed to ensure that everything is synchronized since threads need to drop the + // deoptimization_status_lock_ while deoptimizing methods. + void WaitForDeoptimizationToFinish(art::Thread* self) + RELEASE(deoptimization_status_lock_) REQUIRES(!art::Locks::mutator_lock_); + + void WaitForDeoptimizationToFinishLocked(art::Thread* self) + REQUIRES(deoptimization_status_lock_, !art::Locks::mutator_lock_); + + void AddDeoptimizeAllMethodsLocked(art::Thread* self) + RELEASE(deoptimization_status_lock_) + REQUIRES(!art::Roles::uninterruptible_, !art::Locks::mutator_lock_); + + void RemoveDeoptimizeAllMethodsLocked(art::Thread* self) + RELEASE(deoptimization_status_lock_) + REQUIRES(!art::Roles::uninterruptible_, !art::Locks::mutator_lock_); + + void PerformGlobalDeoptimization(art::Thread* self) + RELEASE(deoptimization_status_lock_) + REQUIRES(!art::Roles::uninterruptible_, !art::Locks::mutator_lock_); + + void PerformGlobalUndeoptimization(art::Thread* self) + RELEASE(deoptimization_status_lock_) + REQUIRES(!art::Roles::uninterruptible_, !art::Locks::mutator_lock_); + + void PerformLimitedDeoptimization(art::Thread* self, art::ArtMethod* method) + RELEASE(deoptimization_status_lock_) + REQUIRES(!art::Roles::uninterruptible_, !art::Locks::mutator_lock_); + + void PerformLimitedUndeoptimization(art::Thread* self, art::ArtMethod* method) + RELEASE(deoptimization_status_lock_) + REQUIRES(!art::Roles::uninterruptible_, !art::Locks::mutator_lock_); + + static constexpr const char* kDeoptManagerInstrumentationKey = "JVMTI_DeoptManager"; + // static constexpr const char* kDeoptManagerThreadName = "JVMTI_DeoptManagerWorkerThread"; + + art::Mutex deoptimization_status_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER; + art::ConditionVariable deoptimization_condition_ GUARDED_BY(deoptimization_status_lock_); + bool performing_deoptimization_ GUARDED_BY(deoptimization_status_lock_); + + // Number of times we have gotten requests to deopt everything. + uint32_t global_deopt_count_ GUARDED_BY(deoptimization_status_lock_); + + // Number of users of deoptimization there currently are. + uint32_t deopter_count_ GUARDED_BY(deoptimization_status_lock_); + + // A map from methods to the number of breakpoints in them from all envs. + std::unordered_map<art::ArtMethod*, uint32_t> breakpoint_status_ + GUARDED_BY(deoptimization_status_lock_); + + // The MethodInspectionCallback we use to tell the runtime if we care about particular methods. + JvmtiMethodInspectionCallback inspection_callback_; + + // Helper for setting up/tearing-down for deoptimization. + friend class ScopedDeoptimizationContext; +}; + +} // namespace openjdkjvmti +#endif // ART_OPENJDKJVMTI_DEOPT_MANAGER_H_ |