1 /* Copyright (C) 2019 The Android Open Source Project 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * 4 * This file implements interfaces from the file jvmti.h. This implementation 5 * is licensed under the same terms as the file jvmti.h. The 6 * copyright and license information for the file jvmti.h follows. 7 * 8 * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. 9 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 10 * 11 * This code is free software; you can redistribute it and/or modify it 12 * under the terms of the GNU General Public License version 2 only, as 13 * published by the Free Software Foundation. Oracle designates this 14 * particular file as subject to the "Classpath" exception as provided 15 * by Oracle in the LICENSE file that accompanied this code. 16 * 17 * This code is distributed in the hope that it will be useful, but WITHOUT 18 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 19 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 20 * version 2 for more details (a copy is included in the LICENSE file that 21 * accompanied this code). 22 * 23 * You should have received a copy of the GNU General Public License version 24 * 2 along with this work; if not, write to the Free Software Foundation, 25 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 26 * 27 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 28 * or visit www.oracle.com if you need additional information or have any 29 * questions. 30 */ 31 32 #ifndef ART_OPENJDKJVMTI_ALLOC_MANAGER_H_ 33 #define ART_OPENJDKJVMTI_ALLOC_MANAGER_H_ 34 35 #include <jvmti.h> 36 37 #include <atomic> 38 39 #include "base/locks.h" 40 #include "base/mutex.h" 41 #include "gc/allocation_listener.h" 42 43 namespace art { 44 template <typename T> class MutableHandle; 45 template <typename T> class ObjPtr; 46 class Thread; 47 namespace mirror { 48 class Class; 49 class Object; 50 } // namespace mirror 51 } // namespace art 52 53 namespace openjdkjvmti { 54 55 class AllocationManager; 56 57 class JvmtiAllocationListener : public art::gc::AllocationListener { 58 public: JvmtiAllocationListener(AllocationManager * manager)59 explicit JvmtiAllocationListener(AllocationManager* manager) : manager_(manager) {} 60 void ObjectAllocated(art::Thread* self, 61 art::ObjPtr<art::mirror::Object>* obj, 62 size_t cnt) override REQUIRES_SHARED(art::Locks::mutator_lock_); 63 bool HasPreAlloc() const override REQUIRES_SHARED(art::Locks::mutator_lock_); 64 void PreObjectAllocated(art::Thread* self, 65 art::MutableHandle<art::mirror::Class> type, 66 size_t* byte_count) override REQUIRES_SHARED(art::Locks::mutator_lock_); 67 68 private: 69 AllocationManager* manager_; 70 }; 71 72 class AllocationManager { 73 public: 74 class AllocationCallback { 75 public: ~AllocationCallback()76 virtual ~AllocationCallback() {} 77 virtual void ObjectAllocated(art::Thread* self, 78 art::ObjPtr<art::mirror::Object>* obj, 79 size_t byte_count) REQUIRES_SHARED(art::Locks::mutator_lock_) = 0; 80 }; 81 82 AllocationManager(); 83 84 void SetAllocListener(AllocationCallback* callback); 85 void RemoveAllocListener(); 86 87 static AllocationManager* Get(); 88 89 void PauseAllocations(art::Thread* self) REQUIRES_SHARED(art::Locks::mutator_lock_); 90 void ResumeAllocations(art::Thread* self) REQUIRES_SHARED(art::Locks::mutator_lock_); 91 92 void EnableAllocationCallback(art::Thread* self) REQUIRES_SHARED(art::Locks::mutator_lock_); 93 void DisableAllocationCallback(art::Thread* self) REQUIRES_SHARED(art::Locks::mutator_lock_); 94 95 private: 96 template<typename T> 97 void PauseForAllocation(art::Thread* self, T msg) REQUIRES_SHARED(art::Locks::mutator_lock_); 98 void IncrListenerInstall(art::Thread* self) REQUIRES_SHARED(art::Locks::mutator_lock_); 99 void DecrListenerInstall(art::Thread* self) REQUIRES_SHARED(art::Locks::mutator_lock_); 100 101 AllocationCallback* callback_ = nullptr; 102 uint32_t listener_refcount_ GUARDED_BY(alloc_listener_mutex_) = 0; 103 std::atomic<bool> allocations_paused_ever_ = false; 104 std::atomic<art::Thread*> allocations_paused_thread_ = nullptr; 105 std::atomic<bool> callback_enabled_ = false; 106 std::unique_ptr<JvmtiAllocationListener> alloc_listener_ = nullptr; 107 art::Mutex alloc_listener_mutex_ ACQUIRED_AFTER(art::Locks::user_code_suspension_lock_); 108 art::ConditionVariable alloc_pause_cv_; 109 110 friend class JvmtiAllocationListener; 111 }; 112 113 } // namespace openjdkjvmti 114 115 #endif // ART_OPENJDKJVMTI_ALLOC_MANAGER_H_ 116