1*795d594fSAndroid Build Coastguard Worker /* 2*795d594fSAndroid Build Coastguard Worker * Copyright (C) 2014 The Android Open Source Project 3*795d594fSAndroid Build Coastguard Worker * 4*795d594fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*795d594fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*795d594fSAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*795d594fSAndroid Build Coastguard Worker * 8*795d594fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*795d594fSAndroid Build Coastguard Worker * 10*795d594fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*795d594fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*795d594fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*795d594fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*795d594fSAndroid Build Coastguard Worker * limitations under the License. 15*795d594fSAndroid Build Coastguard Worker */ 16*795d594fSAndroid Build Coastguard Worker 17*795d594fSAndroid Build Coastguard Worker #ifndef ART_RUNTIME_MONITOR_POOL_H_ 18*795d594fSAndroid Build Coastguard Worker #define ART_RUNTIME_MONITOR_POOL_H_ 19*795d594fSAndroid Build Coastguard Worker 20*795d594fSAndroid Build Coastguard Worker #include "monitor.h" 21*795d594fSAndroid Build Coastguard Worker 22*795d594fSAndroid Build Coastguard Worker #include "base/allocator.h" 23*795d594fSAndroid Build Coastguard Worker #include "base/macros.h" 24*795d594fSAndroid Build Coastguard Worker #ifdef __LP64__ 25*795d594fSAndroid Build Coastguard Worker #include <stdint.h> 26*795d594fSAndroid Build Coastguard Worker #include "base/atomic.h" 27*795d594fSAndroid Build Coastguard Worker #include "runtime.h" 28*795d594fSAndroid Build Coastguard Worker #else 29*795d594fSAndroid Build Coastguard Worker #include "base/stl_util.h" // STLDeleteElements 30*795d594fSAndroid Build Coastguard Worker #endif 31*795d594fSAndroid Build Coastguard Worker 32*795d594fSAndroid Build Coastguard Worker namespace art HIDDEN { 33*795d594fSAndroid Build Coastguard Worker 34*795d594fSAndroid Build Coastguard Worker // Abstraction to keep monitors small enough to fit in a lock word (32bits). On 32bit systems the 35*795d594fSAndroid Build Coastguard Worker // monitor id loses the alignment bits of the Monitor*. 36*795d594fSAndroid Build Coastguard Worker class MonitorPool { 37*795d594fSAndroid Build Coastguard Worker public: Create()38*795d594fSAndroid Build Coastguard Worker static MonitorPool* Create() { 39*795d594fSAndroid Build Coastguard Worker #ifndef __LP64__ 40*795d594fSAndroid Build Coastguard Worker return nullptr; 41*795d594fSAndroid Build Coastguard Worker #else 42*795d594fSAndroid Build Coastguard Worker return new MonitorPool(); 43*795d594fSAndroid Build Coastguard Worker #endif 44*795d594fSAndroid Build Coastguard Worker } 45*795d594fSAndroid Build Coastguard Worker CreateMonitor(Thread * self,Thread * owner,ObjPtr<mirror::Object> obj,int32_t hash_code)46*795d594fSAndroid Build Coastguard Worker static Monitor* CreateMonitor(Thread* self, 47*795d594fSAndroid Build Coastguard Worker Thread* owner, 48*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Object> obj, 49*795d594fSAndroid Build Coastguard Worker int32_t hash_code) 50*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) { 51*795d594fSAndroid Build Coastguard Worker #ifndef __LP64__ 52*795d594fSAndroid Build Coastguard Worker Monitor* mon = new Monitor(self, owner, obj, hash_code); 53*795d594fSAndroid Build Coastguard Worker DCHECK_ALIGNED(mon, LockWord::kMonitorIdAlignment); 54*795d594fSAndroid Build Coastguard Worker return mon; 55*795d594fSAndroid Build Coastguard Worker #else 56*795d594fSAndroid Build Coastguard Worker return GetMonitorPool()->CreateMonitorInPool(self, owner, obj, hash_code); 57*795d594fSAndroid Build Coastguard Worker #endif 58*795d594fSAndroid Build Coastguard Worker } 59*795d594fSAndroid Build Coastguard Worker ReleaseMonitor(Thread * self,Monitor * monitor)60*795d594fSAndroid Build Coastguard Worker static void ReleaseMonitor(Thread* self, Monitor* monitor) { 61*795d594fSAndroid Build Coastguard Worker #ifndef __LP64__ 62*795d594fSAndroid Build Coastguard Worker UNUSED(self); 63*795d594fSAndroid Build Coastguard Worker delete monitor; 64*795d594fSAndroid Build Coastguard Worker #else 65*795d594fSAndroid Build Coastguard Worker GetMonitorPool()->ReleaseMonitorToPool(self, monitor); 66*795d594fSAndroid Build Coastguard Worker #endif 67*795d594fSAndroid Build Coastguard Worker } 68*795d594fSAndroid Build Coastguard Worker ReleaseMonitors(Thread * self,MonitorList::Monitors * monitors)69*795d594fSAndroid Build Coastguard Worker static void ReleaseMonitors(Thread* self, MonitorList::Monitors* monitors) { 70*795d594fSAndroid Build Coastguard Worker #ifndef __LP64__ 71*795d594fSAndroid Build Coastguard Worker UNUSED(self); 72*795d594fSAndroid Build Coastguard Worker STLDeleteElements(monitors); 73*795d594fSAndroid Build Coastguard Worker #else 74*795d594fSAndroid Build Coastguard Worker GetMonitorPool()->ReleaseMonitorsToPool(self, monitors); 75*795d594fSAndroid Build Coastguard Worker #endif 76*795d594fSAndroid Build Coastguard Worker } 77*795d594fSAndroid Build Coastguard Worker MonitorFromMonitorId(MonitorId mon_id)78*795d594fSAndroid Build Coastguard Worker static Monitor* MonitorFromMonitorId(MonitorId mon_id) { 79*795d594fSAndroid Build Coastguard Worker #ifndef __LP64__ 80*795d594fSAndroid Build Coastguard Worker return reinterpret_cast<Monitor*>(mon_id << LockWord::kMonitorIdAlignmentShift); 81*795d594fSAndroid Build Coastguard Worker #else 82*795d594fSAndroid Build Coastguard Worker return GetMonitorPool()->LookupMonitor(mon_id); 83*795d594fSAndroid Build Coastguard Worker #endif 84*795d594fSAndroid Build Coastguard Worker } 85*795d594fSAndroid Build Coastguard Worker MonitorIdFromMonitor(Monitor * mon)86*795d594fSAndroid Build Coastguard Worker static MonitorId MonitorIdFromMonitor(Monitor* mon) { 87*795d594fSAndroid Build Coastguard Worker #ifndef __LP64__ 88*795d594fSAndroid Build Coastguard Worker return reinterpret_cast<MonitorId>(mon) >> LockWord::kMonitorIdAlignmentShift; 89*795d594fSAndroid Build Coastguard Worker #else 90*795d594fSAndroid Build Coastguard Worker return mon->GetMonitorId(); 91*795d594fSAndroid Build Coastguard Worker #endif 92*795d594fSAndroid Build Coastguard Worker } 93*795d594fSAndroid Build Coastguard Worker ComputeMonitorId(Monitor * mon,Thread * self)94*795d594fSAndroid Build Coastguard Worker static MonitorId ComputeMonitorId(Monitor* mon, Thread* self) { 95*795d594fSAndroid Build Coastguard Worker #ifndef __LP64__ 96*795d594fSAndroid Build Coastguard Worker UNUSED(self); 97*795d594fSAndroid Build Coastguard Worker return MonitorIdFromMonitor(mon); 98*795d594fSAndroid Build Coastguard Worker #else 99*795d594fSAndroid Build Coastguard Worker return GetMonitorPool()->ComputeMonitorIdInPool(mon, self); 100*795d594fSAndroid Build Coastguard Worker #endif 101*795d594fSAndroid Build Coastguard Worker } 102*795d594fSAndroid Build Coastguard Worker GetMonitorPool()103*795d594fSAndroid Build Coastguard Worker static MonitorPool* GetMonitorPool() { 104*795d594fSAndroid Build Coastguard Worker #ifndef __LP64__ 105*795d594fSAndroid Build Coastguard Worker return nullptr; 106*795d594fSAndroid Build Coastguard Worker #else 107*795d594fSAndroid Build Coastguard Worker return Runtime::Current()->GetMonitorPool(); 108*795d594fSAndroid Build Coastguard Worker #endif 109*795d594fSAndroid Build Coastguard Worker } 110*795d594fSAndroid Build Coastguard Worker ~MonitorPool()111*795d594fSAndroid Build Coastguard Worker ~MonitorPool() { 112*795d594fSAndroid Build Coastguard Worker #ifdef __LP64__ 113*795d594fSAndroid Build Coastguard Worker FreeInternal(); 114*795d594fSAndroid Build Coastguard Worker #endif 115*795d594fSAndroid Build Coastguard Worker } 116*795d594fSAndroid Build Coastguard Worker 117*795d594fSAndroid Build Coastguard Worker private: 118*795d594fSAndroid Build Coastguard Worker #ifdef __LP64__ 119*795d594fSAndroid Build Coastguard Worker // When we create a monitor pool, threads have not been initialized, yet, so ignore thread-safety 120*795d594fSAndroid Build Coastguard Worker // analysis. 121*795d594fSAndroid Build Coastguard Worker MonitorPool() NO_THREAD_SAFETY_ANALYSIS; 122*795d594fSAndroid Build Coastguard Worker 123*795d594fSAndroid Build Coastguard Worker void AllocateChunk() REQUIRES(Locks::allocated_monitor_ids_lock_); 124*795d594fSAndroid Build Coastguard Worker 125*795d594fSAndroid Build Coastguard Worker // Release all chunks and metadata. This is done on shutdown, where threads have been destroyed, 126*795d594fSAndroid Build Coastguard Worker // so ignore thead-safety analysis. 127*795d594fSAndroid Build Coastguard Worker void FreeInternal() NO_THREAD_SAFETY_ANALYSIS; 128*795d594fSAndroid Build Coastguard Worker 129*795d594fSAndroid Build Coastguard Worker Monitor* CreateMonitorInPool(Thread* self, 130*795d594fSAndroid Build Coastguard Worker Thread* owner, 131*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Object> obj, 132*795d594fSAndroid Build Coastguard Worker int32_t hash_code) 133*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_); 134*795d594fSAndroid Build Coastguard Worker 135*795d594fSAndroid Build Coastguard Worker void ReleaseMonitorToPool(Thread* self, Monitor* monitor); 136*795d594fSAndroid Build Coastguard Worker void ReleaseMonitorsToPool(Thread* self, MonitorList::Monitors* monitors); 137*795d594fSAndroid Build Coastguard Worker 138*795d594fSAndroid Build Coastguard Worker // Note: This is safe as we do not ever move chunks. All needed entries in the monitor_chunks_ 139*795d594fSAndroid Build Coastguard Worker // data structure are read-only once we get here. Updates happen-before this call because 140*795d594fSAndroid Build Coastguard Worker // the lock word was stored with release semantics and we read it with acquire semantics to 141*795d594fSAndroid Build Coastguard Worker // retrieve the id. LookupMonitor(MonitorId mon_id)142*795d594fSAndroid Build Coastguard Worker Monitor* LookupMonitor(MonitorId mon_id) { 143*795d594fSAndroid Build Coastguard Worker size_t offset = MonitorIdToOffset(mon_id); 144*795d594fSAndroid Build Coastguard Worker size_t index = offset / kChunkSize; 145*795d594fSAndroid Build Coastguard Worker size_t top_index = index / kMaxListSize; 146*795d594fSAndroid Build Coastguard Worker size_t list_index = index % kMaxListSize; 147*795d594fSAndroid Build Coastguard Worker size_t offset_in_chunk = offset % kChunkSize; 148*795d594fSAndroid Build Coastguard Worker uintptr_t base = monitor_chunks_[top_index][list_index]; 149*795d594fSAndroid Build Coastguard Worker return reinterpret_cast<Monitor*>(base + offset_in_chunk); 150*795d594fSAndroid Build Coastguard Worker } 151*795d594fSAndroid Build Coastguard Worker IsInChunk(uintptr_t base_addr,Monitor * mon)152*795d594fSAndroid Build Coastguard Worker static bool IsInChunk(uintptr_t base_addr, Monitor* mon) { 153*795d594fSAndroid Build Coastguard Worker uintptr_t mon_ptr = reinterpret_cast<uintptr_t>(mon); 154*795d594fSAndroid Build Coastguard Worker return base_addr <= mon_ptr && (mon_ptr - base_addr < kChunkSize); 155*795d594fSAndroid Build Coastguard Worker } 156*795d594fSAndroid Build Coastguard Worker ComputeMonitorIdInPool(Monitor * mon,Thread * self)157*795d594fSAndroid Build Coastguard Worker MonitorId ComputeMonitorIdInPool(Monitor* mon, Thread* self) { 158*795d594fSAndroid Build Coastguard Worker MutexLock mu(self, *Locks::allocated_monitor_ids_lock_); 159*795d594fSAndroid Build Coastguard Worker for (size_t i = 0; i <= current_chunk_list_index_; ++i) { 160*795d594fSAndroid Build Coastguard Worker for (size_t j = 0; j < ChunkListCapacity(i); ++j) { 161*795d594fSAndroid Build Coastguard Worker if (j >= num_chunks_ && i == current_chunk_list_index_) { 162*795d594fSAndroid Build Coastguard Worker break; 163*795d594fSAndroid Build Coastguard Worker } 164*795d594fSAndroid Build Coastguard Worker uintptr_t chunk_addr = monitor_chunks_[i][j]; 165*795d594fSAndroid Build Coastguard Worker if (IsInChunk(chunk_addr, mon)) { 166*795d594fSAndroid Build Coastguard Worker return OffsetToMonitorId( 167*795d594fSAndroid Build Coastguard Worker reinterpret_cast<uintptr_t>(mon) - chunk_addr 168*795d594fSAndroid Build Coastguard Worker + i * (kMaxListSize * kChunkSize) + j * kChunkSize); 169*795d594fSAndroid Build Coastguard Worker } 170*795d594fSAndroid Build Coastguard Worker } 171*795d594fSAndroid Build Coastguard Worker } 172*795d594fSAndroid Build Coastguard Worker LOG(FATAL) << "Did not find chunk that contains monitor."; 173*795d594fSAndroid Build Coastguard Worker return 0; 174*795d594fSAndroid Build Coastguard Worker } 175*795d594fSAndroid Build Coastguard Worker MonitorIdToOffset(MonitorId id)176*795d594fSAndroid Build Coastguard Worker static constexpr size_t MonitorIdToOffset(MonitorId id) { 177*795d594fSAndroid Build Coastguard Worker return id << 3; 178*795d594fSAndroid Build Coastguard Worker } 179*795d594fSAndroid Build Coastguard Worker OffsetToMonitorId(size_t offset)180*795d594fSAndroid Build Coastguard Worker static constexpr MonitorId OffsetToMonitorId(size_t offset) { 181*795d594fSAndroid Build Coastguard Worker return static_cast<MonitorId>(offset >> 3); 182*795d594fSAndroid Build Coastguard Worker } 183*795d594fSAndroid Build Coastguard Worker ChunkListCapacity(size_t index)184*795d594fSAndroid Build Coastguard Worker static constexpr size_t ChunkListCapacity(size_t index) { 185*795d594fSAndroid Build Coastguard Worker return kInitialChunkStorage << index; 186*795d594fSAndroid Build Coastguard Worker } 187*795d594fSAndroid Build Coastguard Worker 188*795d594fSAndroid Build Coastguard Worker // TODO: There are assumptions in the code that monitor addresses are 8B aligned (>>3). 189*795d594fSAndroid Build Coastguard Worker static constexpr size_t kMonitorAlignment = 8; 190*795d594fSAndroid Build Coastguard Worker // Size of a monitor, rounded up to a multiple of alignment. 191*795d594fSAndroid Build Coastguard Worker static constexpr size_t kAlignedMonitorSize = (sizeof(Monitor) + kMonitorAlignment - 1) & 192*795d594fSAndroid Build Coastguard Worker -kMonitorAlignment; 193*795d594fSAndroid Build Coastguard Worker // Size of the chunks holding the actual monitors. The bottom bits of the monitor id are the 194*795d594fSAndroid Build Coastguard Worker // index into such a chunk. We can collapse this to the actually used storage 195*795d594fSAndroid Build Coastguard Worker // in a chunk, i.e., kChunkCapacity * kAlignedMonitorSize, but this would mean proper divisions. 196*795d594fSAndroid Build Coastguard Worker static constexpr size_t kChunkSize = 4096; 197*795d594fSAndroid Build Coastguard Worker static_assert(IsPowerOfTwo(kChunkSize), "kChunkSize must be power of 2"); 198*795d594fSAndroid Build Coastguard Worker static constexpr size_t kChunkCapacity = kChunkSize / kAlignedMonitorSize; 199*795d594fSAndroid Build Coastguard Worker // The number of chunks of storage that can be referenced by the initial chunk list. 200*795d594fSAndroid Build Coastguard Worker // The total number of usable monitor chunks is typically 255 times this number, so it 201*795d594fSAndroid Build Coastguard Worker // should be large enough that we don't run out. We run out of address bits if it's > 512. 202*795d594fSAndroid Build Coastguard Worker // Currently we set it a bit smaller, to save half a page per process. We make it tiny in 203*795d594fSAndroid Build Coastguard Worker // debug builds to catch growth errors. The only value we really expect to tune. 204*795d594fSAndroid Build Coastguard Worker static constexpr size_t kInitialChunkStorage = kIsDebugBuild ? 8U : 256U; 205*795d594fSAndroid Build Coastguard Worker static_assert(IsPowerOfTwo(kInitialChunkStorage), "kInitialChunkStorage must be power of 2"); 206*795d594fSAndroid Build Coastguard Worker // The number of lists, each containing pointers to storage chunks. 207*795d594fSAndroid Build Coastguard Worker static constexpr size_t kMaxChunkLists = 8; // Dictated by 3 bit index. Don't increase above 8. 208*795d594fSAndroid Build Coastguard Worker static_assert(IsPowerOfTwo(kMaxChunkLists), "kMaxChunkLists must be power of 2"); 209*795d594fSAndroid Build Coastguard Worker static constexpr size_t kMaxListSize = kInitialChunkStorage << (kMaxChunkLists - 1); 210*795d594fSAndroid Build Coastguard Worker // We lose 3 bits in monitor id due to 3 bit monitor_chunks_ index, and gain it back from 211*795d594fSAndroid Build Coastguard Worker // the 3 bit alignment constraint on monitors: 212*795d594fSAndroid Build Coastguard Worker static_assert(kMaxListSize * kChunkSize < (1 << LockWord::kMonitorIdSize), 213*795d594fSAndroid Build Coastguard Worker "Monitor id bits don't fit"); 214*795d594fSAndroid Build Coastguard Worker static_assert(IsPowerOfTwo(kMaxListSize), "kMaxListSize must be power of 2"); 215*795d594fSAndroid Build Coastguard Worker 216*795d594fSAndroid Build Coastguard Worker // Array of pointers to lists (again arrays) of pointers to chunks containing monitors. 217*795d594fSAndroid Build Coastguard Worker // Zeroth entry points to a list (array) of kInitialChunkStorage pointers to chunks. 218*795d594fSAndroid Build Coastguard Worker // Each subsequent list as twice as large as the preceding one. 219*795d594fSAndroid Build Coastguard Worker // Monitor Ids are effectively interpreted as follows: 220*795d594fSAndroid Build Coastguard Worker // Top 3 bits (of 28): index into monitor_chunks_. 221*795d594fSAndroid Build Coastguard Worker // Next 16 bits: index into the chunk list, i.e. monitor_chunks_[i]. 222*795d594fSAndroid Build Coastguard Worker // Last 9 bits: offset within chunk, expressed as multiple of kMonitorAlignment. 223*795d594fSAndroid Build Coastguard Worker // If we set kInitialChunkStorage to 512, this would allow us to use roughly 128K chunks of 224*795d594fSAndroid Build Coastguard Worker // monitors, which is 0.5GB of monitors. With this maximum setting, the largest chunk list 225*795d594fSAndroid Build Coastguard Worker // contains 64K entries, and we make full use of the available index space. With a 226*795d594fSAndroid Build Coastguard Worker // kInitialChunkStorage value of 256, this is proportionately reduced to 0.25GB of monitors. 227*795d594fSAndroid Build Coastguard Worker // Updates to monitor_chunks_ are guarded by allocated_monitor_ids_lock_ . 228*795d594fSAndroid Build Coastguard Worker // No field in this entire data structure is ever updated once a monitor id whose lookup 229*795d594fSAndroid Build Coastguard Worker // requires it has been made visible to another thread. Thus readers never race with 230*795d594fSAndroid Build Coastguard Worker // updates, in spite of the fact that they acquire no locks. 231*795d594fSAndroid Build Coastguard Worker uintptr_t* monitor_chunks_[kMaxChunkLists]; // uintptr_t is really a Monitor* . 232*795d594fSAndroid Build Coastguard Worker // Highest currently used index in monitor_chunks_ . Used for newly allocated chunks. 233*795d594fSAndroid Build Coastguard Worker size_t current_chunk_list_index_ GUARDED_BY(Locks::allocated_monitor_ids_lock_); 234*795d594fSAndroid Build Coastguard Worker // Number of chunk pointers stored in monitor_chunks_[current_chunk_list_index_] so far. 235*795d594fSAndroid Build Coastguard Worker size_t num_chunks_ GUARDED_BY(Locks::allocated_monitor_ids_lock_); 236*795d594fSAndroid Build Coastguard Worker // After the initial allocation, this is always equal to 237*795d594fSAndroid Build Coastguard Worker // ChunkListCapacity(current_chunk_list_index_). 238*795d594fSAndroid Build Coastguard Worker size_t current_chunk_list_capacity_ GUARDED_BY(Locks::allocated_monitor_ids_lock_); 239*795d594fSAndroid Build Coastguard Worker 240*795d594fSAndroid Build Coastguard Worker using Allocator = TrackingAllocator<uint8_t, kAllocatorTagMonitorPool>; 241*795d594fSAndroid Build Coastguard Worker Allocator allocator_; 242*795d594fSAndroid Build Coastguard Worker 243*795d594fSAndroid Build Coastguard Worker // Start of free list of monitors. 244*795d594fSAndroid Build Coastguard Worker // Note: these point to the right memory regions, but do *not* denote initialized objects. 245*795d594fSAndroid Build Coastguard Worker Monitor* first_free_ GUARDED_BY(Locks::allocated_monitor_ids_lock_); 246*795d594fSAndroid Build Coastguard Worker #endif 247*795d594fSAndroid Build Coastguard Worker }; 248*795d594fSAndroid Build Coastguard Worker 249*795d594fSAndroid Build Coastguard Worker } // namespace art 250*795d594fSAndroid Build Coastguard Worker 251*795d594fSAndroid Build Coastguard Worker #endif // ART_RUNTIME_MONITOR_POOL_H_ 252