1 /* 2 * Copyright (c) 2021 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef PANDA_RUNTIME_MONITOR_POOL_H_ 17 #define PANDA_RUNTIME_MONITOR_POOL_H_ 18 19 #include "libpandabase/os/mutex.h" 20 #include "runtime/include/mem/panda_containers.h" 21 #include "runtime/include/object_header.h" 22 #include "runtime/mark_word.h" 23 #include "runtime/mem/heap_manager.h" 24 #include "runtime/mem/internal_allocator.h" 25 #include "runtime/monitor.h" 26 27 namespace panda { 28 29 class MonitorPool { 30 public: 31 // Likely, we do not need to copy monitor pool 32 NO_COPY_SEMANTIC(MonitorPool); 33 NO_MOVE_SEMANTIC(MonitorPool); 34 35 static constexpr Monitor::MonitorId MAX_MONITOR_ID = MarkWord::MONITOR_POINTER_MAX_COUNT; 36 37 template <class Callback> EnumerateMonitors(const Callback & cb)38 void EnumerateMonitors(const Callback &cb) 39 { 40 os::memory::LockHolder lock(pool_lock_); 41 for (auto &iter : monitors_) { 42 if (!cb(iter.second)) { 43 break; 44 } 45 } 46 } 47 48 template <class Callback> DeflateMonitorsWithCallBack(const Callback & cb)49 void DeflateMonitorsWithCallBack(const Callback &cb) 50 { 51 os::memory::LockHolder lock(pool_lock_); 52 for (auto monitor_iter = monitors_.begin(); monitor_iter != monitors_.end();) { 53 auto monitor = monitor_iter->second; 54 if (cb(monitor) && monitor->DeflateInternal()) { 55 monitor_iter = monitors_.erase(monitor_iter); 56 allocator_->Delete(monitor); 57 } else { 58 monitor_iter++; 59 } 60 } 61 } 62 MonitorPool(mem::InternalAllocatorPtr allocator)63 explicit MonitorPool(mem::InternalAllocatorPtr allocator) : monitors_(allocator->Adapter()) 64 { 65 last_id_ = 0; 66 allocator_ = allocator; 67 } 68 ~MonitorPool()69 ~MonitorPool() 70 { 71 for (auto &iter : monitors_) { 72 if (iter.second != nullptr) { 73 allocator_->Delete(iter.second); 74 } 75 } 76 } 77 78 static Monitor *CreateMonitor(PandaVM *vm, ObjectHeader *obj); 79 80 static Monitor *LookupMonitor(PandaVM *vm, Monitor::MonitorId id); 81 82 static void FreeMonitor(PandaVM *vm, Monitor::MonitorId id); 83 84 void DeflateMonitors(); 85 86 private: 87 mem::InternalAllocatorPtr allocator_; 88 // Lock for private data protection. 89 os::memory::Mutex pool_lock_; 90 91 Monitor::MonitorId last_id_ GUARDED_BY(pool_lock_); 92 PandaUnorderedMap<Monitor::MonitorId, Monitor *> monitors_ GUARDED_BY(pool_lock_); 93 }; 94 95 } // namespace panda 96 97 #endif // PANDA_RUNTIME_MONITOR_POOL_H_ 98