namespace art HIDDEN { namespace gc { namespace accounting {
using android::base::StringPrintf;
template<size_t kAlignment>
size_t SpaceBitmap<kAlignment>::ComputeBitmapSize(uint64_t capacity) { // Number of space (heap) bytes covered by one bitmap word. // (Word size in bytes = `sizeof(intptr_t)`, which is expected to be // 4 on a 32-bit architecture and 8 on a 64-bit one.) const uint64_t kBytesCoveredPerWord = kAlignment * kBitsPerIntPtrT; // Calculate the number of words required to cover a space (heap) // having a size of `capacity` bytes. return (RoundUp(capacity, kBytesCoveredPerWord) / kBytesCoveredPerWord) * sizeof(intptr_t);
}
template<size_t kAlignment>
SpaceBitmap<kAlignment> SpaceBitmap<kAlignment>::Create( const std::string& name, uint8_t* heap_begin, size_t heap_capacity) { // Round up since `heap_capacity` is not necessarily a multiple of `kAlignment * kBitsPerIntPtrT` // (we represent one word as an `intptr_t`). const size_t bitmap_size = ComputeBitmapSize(heap_capacity);
std::string error_msg;
MemMap mem_map = MemMap::MapAnonymous(name.c_str(),
bitmap_size,
PROT_READ | PROT_WRITE, /*low_4gb=*/ false,
&error_msg); if (UNLIKELY(!mem_map.IsValid())) {
LOG(ERROR) << "Failed to allocate bitmap " << name << ": " << error_msg; return SpaceBitmap<kAlignment>();
} return CreateFromMemMap(name, std::move(mem_map), heap_begin, heap_capacity);
}
template<size_t kAlignment> void SpaceBitmap<kAlignment>::SetHeapLimit(uintptr_t new_end) {
DCHECK_ALIGNED(new_end, kBitsPerIntPtrT * kAlignment);
size_t new_size = OffsetToIndex(new_end - heap_begin_) * sizeof(intptr_t); if (new_size < bitmap_size_) {
bitmap_size_ = new_size;
}
heap_limit_ = new_end; // Not sure if doing this trim is necessary, since nothing past the end of the heap capacity // should be marked.
}
if (Runtime::Current()->IsRunningOnMemoryTool()) { // For memory tool, make the buffer large enough to hold all allocations. This is done since // we get the size of objects (and hence read the class) inside of the freeing logic. This can // cause crashes for unloaded classes since the class may get zeroed out before it is read. // See b/131542326 for (size_t i = start; i <= end; i++) {
uintptr_t garbage =
live[i].load(std::memory_order_relaxed) & ~mark[i].load(std::memory_order_relaxed);
buffer_size += POPCOUNT(garbage);
}
}
std::vector<mirror::Object*> pointer_buf(buffer_size);
mirror::Object** cur_pointer = &pointer_buf[0];
mirror::Object** pointer_end = cur_pointer + (buffer_size - kBitsPerIntPtrT);
for (size_t i = start; i <= end; i++) {
uintptr_t garbage =
live[i].load(std::memory_order_relaxed) & ~mark[i].load(std::memory_order_relaxed); if (UNLIKELY(garbage != 0)) {
uintptr_t ptr_base = IndexToOffset(i) + live_bitmap.heap_begin_; do { const size_t shift = CTZ(garbage);
garbage ^= (static_cast<uintptr_t>(1)) << shift;
*cur_pointer++ = reinterpret_cast<mirror::Object*>(ptr_base + shift * kAlignment);
} while (garbage != 0); // Make sure that there are always enough slots available for an // entire word of one bits. if (cur_pointer >= pointer_end) {
(*callback)(cur_pointer - &pointer_buf[0], &pointer_buf[0], arg);
cur_pointer = &pointer_buf[0];
}
}
} if (cur_pointer > &pointer_buf[0]) {
(*callback)(cur_pointer - &pointer_buf[0], &pointer_buf[0], arg);
}
}
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.