diff options
-rw-r--r-- | runtime/gc/space/bump_pointer_space.cc | 25 | ||||
-rw-r--r-- | runtime/gc/space/bump_pointer_space.h | 7 |
2 files changed, 19 insertions, 13 deletions
diff --git a/runtime/gc/space/bump_pointer_space.cc b/runtime/gc/space/bump_pointer_space.cc index 2e07bd3..f7bdc4c 100644 --- a/runtime/gc/space/bump_pointer_space.cc +++ b/runtime/gc/space/bump_pointer_space.cc @@ -44,9 +44,8 @@ BumpPointerSpace::BumpPointerSpace(const std::string& name, byte* begin, byte* l growth_end_(limit), objects_allocated_(0), bytes_allocated_(0), block_lock_("Block lock"), + main_block_size_(0), num_blocks_(0) { - CHECK_GE(Capacity(), sizeof(BlockHeader)); - end_ += sizeof(BlockHeader); } BumpPointerSpace::BumpPointerSpace(const std::string& name, MemMap* mem_map) @@ -55,9 +54,8 @@ BumpPointerSpace::BumpPointerSpace(const std::string& name, MemMap* mem_map) growth_end_(mem_map->End()), objects_allocated_(0), bytes_allocated_(0), block_lock_("Block lock"), + main_block_size_(0), num_blocks_(0) { - CHECK_GE(Capacity(), sizeof(BlockHeader)); - end_ += sizeof(BlockHeader); } mirror::Object* BumpPointerSpace::Alloc(Thread*, size_t num_bytes, size_t* bytes_allocated) { @@ -78,13 +76,14 @@ void BumpPointerSpace::Clear() { CHECK_NE(madvise(Begin(), Limit() - Begin(), MADV_DONTNEED), -1) << "madvise failed"; // Reset the end of the space back to the beginning, we move the end forward as we allocate // objects. - SetEnd(Begin() + sizeof(BlockHeader)); + SetEnd(Begin()); objects_allocated_ = 0; bytes_allocated_ = 0; growth_end_ = Limit(); { MutexLock mu(Thread::Current(), block_lock_); num_blocks_ = 0; + main_block_size_ = 0; } } @@ -115,9 +114,8 @@ void BumpPointerSpace::RevokeAllThreadLocalBuffers() { } void BumpPointerSpace::UpdateMainBlock() { - BlockHeader* header = reinterpret_cast<BlockHeader*>(Begin()); - header->size_ = Size() - sizeof(BlockHeader); DCHECK_EQ(num_blocks_, 0U); + main_block_size_ = Size(); } // Returns the start of the storage. @@ -139,7 +137,7 @@ byte* BumpPointerSpace::AllocBlock(size_t bytes) { void BumpPointerSpace::Walk(ObjectCallback* callback, void* arg) { byte* pos = Begin(); - + byte* main_end = pos; { MutexLock mu(Thread::Current(), block_lock_); // If we have 0 blocks then we need to update the main header since we have bump pointer style @@ -147,8 +145,15 @@ void BumpPointerSpace::Walk(ObjectCallback* callback, void* arg) { if (num_blocks_ == 0) { UpdateMainBlock(); } + main_end += main_block_size_; } - + // Walk all of the objects in the main block first. + while (pos < main_end) { + mirror::Object* obj = reinterpret_cast<mirror::Object*>(pos); + callback(obj, arg); + pos = reinterpret_cast<byte*>(GetNextObject(obj)); + } + // Walk the other blocks (currently only TLABs). while (pos < End()) { BlockHeader* header = reinterpret_cast<BlockHeader*>(pos); size_t block_size = header->size_; @@ -167,7 +172,7 @@ void BumpPointerSpace::Walk(ObjectCallback* callback, void* arg) { } bool BumpPointerSpace::IsEmpty() const { - return Size() == sizeof(BlockHeader); + return Begin() == End(); } uint64_t BumpPointerSpace::GetBytesAllocated() { diff --git a/runtime/gc/space/bump_pointer_space.h b/runtime/gc/space/bump_pointer_space.h index ddd17be..d7e6f5b 100644 --- a/runtime/gc/space/bump_pointer_space.h +++ b/runtime/gc/space/bump_pointer_space.h @@ -139,15 +139,16 @@ class BumpPointerSpace : public ContinuousMemMapAllocSpace { // The main block is an unbounded block where objects go when there are no other blocks. This // enables us to maintain tightly packed objects when you are not using thread local buffers for - // allocation. - // The main block is also the block which starts at address 0. + // allocation. The main block starts at the space Begin(). void UpdateMainBlock() EXCLUSIVE_LOCKS_REQUIRED(block_lock_); byte* growth_end_; AtomicInteger objects_allocated_; // Accumulated from revoked thread local regions. AtomicInteger bytes_allocated_; // Accumulated from revoked thread local regions. Mutex block_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER; - + // The objects at the start of the space are stored in the main block. The main block doesn't + // have a header, this lets us walk empty spaces which are mprotected. + size_t main_block_size_ GUARDED_BY(block_lock_); // The number of blocks in the space, if it is 0 then the space has one long continuous block // which doesn't have an updated header. size_t num_blocks_ GUARDED_BY(block_lock_); |