144 lines
		
	
	
		
			4.9 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			144 lines
		
	
	
		
			4.9 KiB
		
	
	
	
		
			C++
		
	
	
	
| /*
 | |
|  * Copyright (C) 2014 The Android Open Source Project
 | |
|  *
 | |
|  * Licensed under the Apache License, Version 2.0 (the "License");
 | |
|  * you may not use this file except in compliance with the License.
 | |
|  * You may obtain a copy of the License at
 | |
|  *
 | |
|  *      http://www.apache.org/licenses/LICENSE-2.0
 | |
|  *
 | |
|  * Unless required by applicable law or agreed to in writing, software
 | |
|  * distributed under the License is distributed on an "AS IS" BASIS,
 | |
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | |
|  * See the License for the specific language governing permissions and
 | |
|  * limitations under the License.
 | |
|  */
 | |
| 
 | |
| #include "zygote_space.h"
 | |
| 
 | |
| #include "base/mutex-inl.h"
 | |
| #include "base/utils.h"
 | |
| #include "gc/accounting/card_table-inl.h"
 | |
| #include "gc/accounting/space_bitmap-inl.h"
 | |
| #include "gc/heap.h"
 | |
| #include "mirror/object-readbarrier-inl.h"
 | |
| #include "runtime.h"
 | |
| #include "thread-current-inl.h"
 | |
| 
 | |
| namespace art {
 | |
| namespace gc {
 | |
| namespace space {
 | |
| 
 | |
| class CountObjectsAllocated {
 | |
|  public:
 | |
|   explicit CountObjectsAllocated(size_t* objects_allocated)
 | |
|       : objects_allocated_(objects_allocated) {}
 | |
| 
 | |
|   void operator()(mirror::Object* obj ATTRIBUTE_UNUSED) const {
 | |
|     ++*objects_allocated_;
 | |
|   }
 | |
| 
 | |
|  private:
 | |
|   size_t* const objects_allocated_;
 | |
| };
 | |
| 
 | |
| ZygoteSpace* ZygoteSpace::Create(const std::string& name,
 | |
|                                  MemMap&& mem_map,
 | |
|                                  accounting::ContinuousSpaceBitmap&& live_bitmap,
 | |
|                                  accounting::ContinuousSpaceBitmap&& mark_bitmap) {
 | |
|   DCHECK(live_bitmap.IsValid());
 | |
|   DCHECK(mark_bitmap.IsValid());
 | |
|   size_t objects_allocated = 0;
 | |
|   CountObjectsAllocated visitor(&objects_allocated);
 | |
|   ReaderMutexLock mu(Thread::Current(), *Locks::heap_bitmap_lock_);
 | |
|   live_bitmap.VisitMarkedRange(reinterpret_cast<uintptr_t>(mem_map.Begin()),
 | |
|                                reinterpret_cast<uintptr_t>(mem_map.End()), visitor);
 | |
|   ZygoteSpace* zygote_space = new ZygoteSpace(name, std::move(mem_map), objects_allocated);
 | |
|   zygote_space->live_bitmap_ = std::move(live_bitmap);
 | |
|   zygote_space->mark_bitmap_ = std::move(mark_bitmap);
 | |
|   return zygote_space;
 | |
| }
 | |
| 
 | |
| void ZygoteSpace::SetMarkBitInLiveObjects() {
 | |
|   GetLiveBitmap()->VisitMarkedRange(reinterpret_cast<uintptr_t>(Begin()),
 | |
|                                     reinterpret_cast<uintptr_t>(Limit()),
 | |
|                                     [](mirror::Object* obj) REQUIRES_SHARED(Locks::mutator_lock_) {
 | |
|                                       bool success = obj->AtomicSetMarkBit(0, 1);
 | |
|                                       CHECK(success);
 | |
|                                     });
 | |
| }
 | |
| 
 | |
| void ZygoteSpace::Clear() {
 | |
|   UNIMPLEMENTED(FATAL);
 | |
|   UNREACHABLE();
 | |
| }
 | |
| 
 | |
| ZygoteSpace::ZygoteSpace(const std::string& name, MemMap&& mem_map, size_t objects_allocated)
 | |
|     : ContinuousMemMapAllocSpace(name,
 | |
|                                  std::move(mem_map),
 | |
|                                  mem_map.Begin(),
 | |
|                                  mem_map.End(),
 | |
|                                  mem_map.End(),
 | |
|                                  kGcRetentionPolicyFullCollect),
 | |
|       objects_allocated_(objects_allocated) {
 | |
| }
 | |
| 
 | |
| void ZygoteSpace::Dump(std::ostream& os) const {
 | |
|   os << GetType()
 | |
|       << " begin=" << reinterpret_cast<void*>(Begin())
 | |
|       << ",end=" << reinterpret_cast<void*>(End())
 | |
|       << ",size=" << PrettySize(Size())
 | |
|       << ",name=\"" << GetName() << "\"]";
 | |
| }
 | |
| 
 | |
| mirror::Object* ZygoteSpace::Alloc(Thread*, size_t, size_t*, size_t*, size_t*) {
 | |
|   UNIMPLEMENTED(FATAL);
 | |
|   UNREACHABLE();
 | |
| }
 | |
| 
 | |
| size_t ZygoteSpace::AllocationSize(mirror::Object*, size_t*) {
 | |
|   UNIMPLEMENTED(FATAL);
 | |
|   UNREACHABLE();
 | |
| }
 | |
| 
 | |
| size_t ZygoteSpace::Free(Thread*, mirror::Object*) {
 | |
|   UNIMPLEMENTED(FATAL);
 | |
|   UNREACHABLE();
 | |
| }
 | |
| 
 | |
| size_t ZygoteSpace::FreeList(Thread*, size_t, mirror::Object**) {
 | |
|   UNIMPLEMENTED(FATAL);
 | |
|   UNREACHABLE();
 | |
| }
 | |
| 
 | |
| bool ZygoteSpace::LogFragmentationAllocFailure(std::ostream&, size_t) {
 | |
|   UNIMPLEMENTED(FATAL);
 | |
|   UNREACHABLE();
 | |
| }
 | |
| 
 | |
| void ZygoteSpace::SweepCallback(size_t num_ptrs, mirror::Object** ptrs, void* arg) {
 | |
|   SweepCallbackContext* context = static_cast<SweepCallbackContext*>(arg);
 | |
|   DCHECK(context->space->IsZygoteSpace());
 | |
|   ZygoteSpace* zygote_space = context->space->AsZygoteSpace();
 | |
|   Locks::heap_bitmap_lock_->AssertExclusiveHeld(context->self);
 | |
|   accounting::CardTable* card_table = Runtime::Current()->GetHeap()->GetCardTable();
 | |
|   // If the bitmaps aren't swapped we need to clear the bits since the GC isn't going to re-swap
 | |
|   // the bitmaps as an optimization.
 | |
|   if (!context->swap_bitmaps) {
 | |
|     accounting::ContinuousSpaceBitmap* bitmap = zygote_space->GetLiveBitmap();
 | |
|     for (size_t i = 0; i < num_ptrs; ++i) {
 | |
|       bitmap->Clear(ptrs[i]);
 | |
|     }
 | |
|   }
 | |
|   // We don't free any actual memory to avoid dirtying the shared zygote pages.
 | |
|   for (size_t i = 0; i < num_ptrs; ++i) {
 | |
|     // Need to mark the card since this will update the mod-union table next GC cycle.
 | |
|     card_table->MarkCard(ptrs[i]);
 | |
|   }
 | |
|   zygote_space->objects_allocated_.fetch_sub(num_ptrs);
 | |
| }
 | |
| 
 | |
| }  // namespace space
 | |
| }  // namespace gc
 | |
| }  // namespace art
 |