#include"base/logging.h"// For VLOG. #include"base/mutex-inl.h" #include"monitor.h" #include"thread-current-inl.h"
namespace art HIDDEN {
namespace mirror { class Object;
} // namespace mirror
MonitorPool::MonitorPool()
: current_chunk_list_index_(0), num_chunks_(0), current_chunk_list_capacity_(0),
first_free_(nullptr) { for (size_t i = 0; i < kMaxChunkLists; ++i) {
monitor_chunks_[i] = nullptr; // Not absolutely required, but ...
}
AllocateChunk(); // Get our first chunk.
}
// Assumes locks are held appropriately when necessary. // We do not need a lock in the constructor, but we need one when in CreateMonitorInPool. void MonitorPool::AllocateChunk() {
DCHECK(first_free_ == nullptr);
// Do we need to allocate another chunk list? if (num_chunks_ == current_chunk_list_capacity_) { if (current_chunk_list_capacity_ != 0U) {
++current_chunk_list_index_;
CHECK_LT(current_chunk_list_index_, kMaxChunkLists) << "Out of space for inflated monitors";
VLOG(monitor) << "Expanding to capacity "
<< 2 * ChunkListCapacity(current_chunk_list_index_) - kInitialChunkStorage;
} // else we're initializing
current_chunk_list_capacity_ = ChunkListCapacity(current_chunk_list_index_);
uintptr_t* new_list = new uintptr_t[current_chunk_list_capacity_]();
DCHECK(monitor_chunks_[current_chunk_list_index_] == nullptr);
monitor_chunks_[current_chunk_list_index_] = new_list;
num_chunks_ = 0;
}
// Allocate the chunk. void* chunk = allocator_.allocate(kChunkSize); // Check we allocated memory.
CHECK_NE(reinterpret_cast<uintptr_t>(nullptr), reinterpret_cast<uintptr_t>(chunk)); // Check it is aligned as we need it.
CHECK_EQ(0U, reinterpret_cast<uintptr_t>(chunk) % kMonitorAlignment);
// Add the chunk.
monitor_chunks_[current_chunk_list_index_][num_chunks_] = reinterpret_cast<uintptr_t>(chunk);
num_chunks_++;
// Set up the free list
Monitor* last = reinterpret_cast<Monitor*>(reinterpret_cast<uintptr_t>(chunk) +
(kChunkCapacity - 1) * kAlignedMonitorSize);
last->next_free_ = nullptr; // Eagerly compute id.
last->monitor_id_ = OffsetToMonitorId(current_chunk_list_index_* (kMaxListSize * kChunkSize)
+ (num_chunks_ - 1) * kChunkSize + (kChunkCapacity - 1) * kAlignedMonitorSize); for (size_t i = 0; i < kChunkCapacity - 1; ++i) {
Monitor* before = reinterpret_cast<Monitor*>(reinterpret_cast<uintptr_t>(last) -
kAlignedMonitorSize);
before->next_free_ = last; // Derive monitor_id from last.
before->monitor_id_ = OffsetToMonitorId(MonitorIdToOffset(last->monitor_id_) -
kAlignedMonitorSize);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.