1 /* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include "zygote_space.h" 18 19 #include "gc/accounting/card_table-inl.h" 20 #include "gc/accounting/space_bitmap-inl.h" 21 #include "gc/heap.h" 22 #include "thread-inl.h" 23 #include "utils.h" 24 25 namespace art { 26 namespace gc { 27 namespace space { 28 29 class CountObjectsAllocated { 30 public: 31 explicit CountObjectsAllocated(size_t* objects_allocated) 32 : objects_allocated_(objects_allocated) {} 33 34 void operator()(mirror::Object* obj ATTRIBUTE_UNUSED) const { 35 ++*objects_allocated_; 36 } 37 38 private: 39 size_t* const objects_allocated_; 40 }; 41 42 ZygoteSpace* ZygoteSpace::Create(const std::string& name, MemMap* mem_map, 43 accounting::ContinuousSpaceBitmap* live_bitmap, 44 accounting::ContinuousSpaceBitmap* mark_bitmap) { 45 DCHECK(live_bitmap != nullptr); 46 DCHECK(mark_bitmap != nullptr); 47 size_t objects_allocated = 0; 48 CountObjectsAllocated visitor(&objects_allocated); 49 ReaderMutexLock mu(Thread::Current(), *Locks::heap_bitmap_lock_); 50 live_bitmap->VisitMarkedRange(reinterpret_cast<uintptr_t>(mem_map->Begin()), 51 reinterpret_cast<uintptr_t>(mem_map->End()), visitor); 52 ZygoteSpace* zygote_space = new ZygoteSpace(name, mem_map, objects_allocated); 53 CHECK(zygote_space->live_bitmap_.get() == nullptr); 54 CHECK(zygote_space->mark_bitmap_.get() == nullptr); 55 zygote_space->live_bitmap_.reset(live_bitmap); 56 zygote_space->mark_bitmap_.reset(mark_bitmap); 57 return zygote_space; 58 } 59 60 void ZygoteSpace::Clear() { 61 UNIMPLEMENTED(FATAL); 62 UNREACHABLE(); 63 } 64 65 ZygoteSpace::ZygoteSpace(const std::string& name, MemMap* mem_map, size_t objects_allocated) 66 : ContinuousMemMapAllocSpace(name, mem_map, mem_map->Begin(), mem_map->End(), mem_map->End(), 67 kGcRetentionPolicyFullCollect), 68 objects_allocated_(objects_allocated) { 69 } 70 71 void ZygoteSpace::Dump(std::ostream& os) const { 72 os << GetType() 73 << " begin=" << reinterpret_cast<void*>(Begin()) 74 << ",end=" << reinterpret_cast<void*>(End()) 75 << ",size=" << PrettySize(Size()) 76 << ",name=\"" << GetName() << "\"]"; 77 } 78 79 mirror::Object* ZygoteSpace::Alloc(Thread*, size_t, size_t*, size_t*, size_t*) { 80 UNIMPLEMENTED(FATAL); 81 UNREACHABLE(); 82 } 83 84 size_t ZygoteSpace::AllocationSize(mirror::Object*, size_t*) { 85 UNIMPLEMENTED(FATAL); 86 UNREACHABLE(); 87 } 88 89 size_t ZygoteSpace::Free(Thread*, mirror::Object*) { 90 UNIMPLEMENTED(FATAL); 91 UNREACHABLE(); 92 } 93 94 size_t ZygoteSpace::FreeList(Thread*, size_t, mirror::Object**) { 95 UNIMPLEMENTED(FATAL); 96 UNREACHABLE(); 97 } 98 99 void ZygoteSpace::LogFragmentationAllocFailure(std::ostream&, size_t) { 100 UNIMPLEMENTED(FATAL); 101 UNREACHABLE(); 102 } 103 104 void ZygoteSpace::SweepCallback(size_t num_ptrs, mirror::Object** ptrs, void* arg) { 105 SweepCallbackContext* context = static_cast<SweepCallbackContext*>(arg); 106 DCHECK(context->space->IsZygoteSpace()); 107 ZygoteSpace* zygote_space = context->space->AsZygoteSpace(); 108 Locks::heap_bitmap_lock_->AssertExclusiveHeld(context->self); 109 accounting::CardTable* card_table = Runtime::Current()->GetHeap()->GetCardTable(); 110 // If the bitmaps aren't swapped we need to clear the bits since the GC isn't going to re-swap 111 // the bitmaps as an optimization. 112 if (!context->swap_bitmaps) { 113 accounting::ContinuousSpaceBitmap* bitmap = zygote_space->GetLiveBitmap(); 114 for (size_t i = 0; i < num_ptrs; ++i) { 115 bitmap->Clear(ptrs[i]); 116 } 117 } 118 // We don't free any actual memory to avoid dirtying the shared zygote pages. 119 for (size_t i = 0; i < num_ptrs; ++i) { 120 // Need to mark the card since this will update the mod-union table next GC cycle. 121 card_table->MarkCard(ptrs[i]); 122 } 123 zygote_space->objects_allocated_.FetchAndSubSequentiallyConsistent(num_ptrs); 124 } 125 126 } // namespace space 127 } // namespace gc 128 } // namespace art 129