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 "base/mutex-inl.h" 20 #include "base/utils.h" 21 #include "gc/accounting/card_table-inl.h" 22 #include "gc/accounting/space_bitmap-inl.h" 23 #include "gc/heap.h" 24 #include "runtime.h" 25 #include "thread-current-inl.h" 26 27 namespace art { 28 namespace gc { 29 namespace space { 30 31 class CountObjectsAllocated { 32 public: 33 explicit CountObjectsAllocated(size_t* objects_allocated) 34 : objects_allocated_(objects_allocated) {} 35 36 void operator()(mirror::Object* obj ATTRIBUTE_UNUSED) const { 37 ++*objects_allocated_; 38 } 39 40 private: 41 size_t* const objects_allocated_; 42 }; 43 44 ZygoteSpace* ZygoteSpace::Create(const std::string& name, MemMap* mem_map, 45 accounting::ContinuousSpaceBitmap* live_bitmap, 46 accounting::ContinuousSpaceBitmap* mark_bitmap) { 47 DCHECK(live_bitmap != nullptr); 48 DCHECK(mark_bitmap != nullptr); 49 size_t objects_allocated = 0; 50 CountObjectsAllocated visitor(&objects_allocated); 51 ReaderMutexLock mu(Thread::Current(), *Locks::heap_bitmap_lock_); 52 live_bitmap->VisitMarkedRange(reinterpret_cast<uintptr_t>(mem_map->Begin()), 53 reinterpret_cast<uintptr_t>(mem_map->End()), visitor); 54 ZygoteSpace* zygote_space = new ZygoteSpace(name, mem_map, objects_allocated); 55 CHECK(zygote_space->live_bitmap_.get() == nullptr); 56 CHECK(zygote_space->mark_bitmap_.get() == nullptr); 57 zygote_space->live_bitmap_.reset(live_bitmap); 58 zygote_space->mark_bitmap_.reset(mark_bitmap); 59 return zygote_space; 60 } 61 62 void ZygoteSpace::Clear() { 63 UNIMPLEMENTED(FATAL); 64 UNREACHABLE(); 65 } 66 67 ZygoteSpace::ZygoteSpace(const std::string& name, MemMap* mem_map, size_t objects_allocated) 68 : ContinuousMemMapAllocSpace(name, mem_map, mem_map->Begin(), mem_map->End(), mem_map->End(), 69 kGcRetentionPolicyFullCollect), 70 objects_allocated_(objects_allocated) { 71 } 72 73 void ZygoteSpace::Dump(std::ostream& os) const { 74 os << GetType() 75 << " begin=" << reinterpret_cast<void*>(Begin()) 76 << ",end=" << reinterpret_cast<void*>(End()) 77 << ",size=" << PrettySize(Size()) 78 << ",name=\"" << GetName() << "\"]"; 79 } 80 81 mirror::Object* ZygoteSpace::Alloc(Thread*, size_t, size_t*, size_t*, size_t*) { 82 UNIMPLEMENTED(FATAL); 83 UNREACHABLE(); 84 } 85 86 size_t ZygoteSpace::AllocationSize(mirror::Object*, size_t*) { 87 UNIMPLEMENTED(FATAL); 88 UNREACHABLE(); 89 } 90 91 size_t ZygoteSpace::Free(Thread*, mirror::Object*) { 92 UNIMPLEMENTED(FATAL); 93 UNREACHABLE(); 94 } 95 96 size_t ZygoteSpace::FreeList(Thread*, size_t, mirror::Object**) { 97 UNIMPLEMENTED(FATAL); 98 UNREACHABLE(); 99 } 100 101 void ZygoteSpace::LogFragmentationAllocFailure(std::ostream&, size_t) { 102 UNIMPLEMENTED(FATAL); 103 UNREACHABLE(); 104 } 105 106 void ZygoteSpace::SweepCallback(size_t num_ptrs, mirror::Object** ptrs, void* arg) { 107 SweepCallbackContext* context = static_cast<SweepCallbackContext*>(arg); 108 DCHECK(context->space->IsZygoteSpace()); 109 ZygoteSpace* zygote_space = context->space->AsZygoteSpace(); 110 Locks::heap_bitmap_lock_->AssertExclusiveHeld(context->self); 111 accounting::CardTable* card_table = Runtime::Current()->GetHeap()->GetCardTable(); 112 // If the bitmaps aren't swapped we need to clear the bits since the GC isn't going to re-swap 113 // the bitmaps as an optimization. 114 if (!context->swap_bitmaps) { 115 accounting::ContinuousSpaceBitmap* bitmap = zygote_space->GetLiveBitmap(); 116 for (size_t i = 0; i < num_ptrs; ++i) { 117 bitmap->Clear(ptrs[i]); 118 } 119 } 120 // We don't free any actual memory to avoid dirtying the shared zygote pages. 121 for (size_t i = 0; i < num_ptrs; ++i) { 122 // Need to mark the card since this will update the mod-union table next GC cycle. 123 card_table->MarkCard(ptrs[i]); 124 } 125 zygote_space->objects_allocated_.FetchAndSubSequentiallyConsistent(num_ptrs); 126 } 127 128 } // namespace space 129 } // namespace gc 130 } // namespace art 131