1 /* 2 * Copyright (C) 2013 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 #ifndef ART_RUNTIME_GC_HEAP_INL_H_ 18 #define ART_RUNTIME_GC_HEAP_INL_H_ 19 20 #include "heap.h" 21 22 #include "debugger.h" 23 #include "gc/accounting/card_table-inl.h" 24 #include "gc/collector/semi_space.h" 25 #include "gc/space/bump_pointer_space-inl.h" 26 #include "gc/space/dlmalloc_space-inl.h" 27 #include "gc/space/large_object_space.h" 28 #include "gc/space/rosalloc_space-inl.h" 29 #include "runtime.h" 30 #include "handle_scope-inl.h" 31 #include "thread.h" 32 #include "thread-inl.h" 33 #include "verify_object-inl.h" 34 35 namespace art { 36 namespace gc { 37 38 template <bool kInstrumented, bool kCheckLargeObject, typename PreFenceVisitor> 39 inline mirror::Object* Heap::AllocObjectWithAllocator(Thread* self, mirror::Class* klass, 40 size_t byte_count, AllocatorType allocator, 41 const PreFenceVisitor& pre_fence_visitor) { 42 if (kIsDebugBuild) { 43 CheckPreconditionsForAllocObject(klass, byte_count); 44 // Since allocation can cause a GC which will need to SuspendAll, make sure all allocations are 45 // done in the runnable state where suspension is expected. 46 CHECK_EQ(self->GetState(), kRunnable); 47 self->AssertThreadSuspensionIsAllowable(); 48 } 49 // Need to check that we arent the large object allocator since the large object allocation code 50 // path this function. If we didn't check we would have an infinite loop. 51 mirror::Object* obj; 52 if (kCheckLargeObject && UNLIKELY(ShouldAllocLargeObject(klass, byte_count))) { 53 obj = AllocLargeObject<kInstrumented, PreFenceVisitor>(self, &klass, byte_count, 54 pre_fence_visitor); 55 if (obj != nullptr) { 56 return obj; 57 } else { 58 // There should be an OOM exception, since we are retrying, clear it. 59 self->ClearException(); 60 } 61 // If the large object allocation failed, try to use the normal spaces (main space, 62 // non moving space). This can happen if there is significant virtual address space 63 // fragmentation. 64 } 65 AllocationTimer alloc_timer(this, &obj); 66 size_t bytes_allocated; 67 size_t usable_size; 68 size_t new_num_bytes_allocated = 0; 69 if (allocator == kAllocatorTypeTLAB) { 70 byte_count = RoundUp(byte_count, space::BumpPointerSpace::kAlignment); 71 } 72 // If we have a thread local allocation we don't need to update bytes allocated. 73 if (allocator == kAllocatorTypeTLAB && byte_count <= self->TlabSize()) { 74 obj = self->AllocTlab(byte_count); 75 DCHECK(obj != nullptr) << "AllocTlab can't fail"; 76 obj->SetClass(klass); 77 if (kUseBakerOrBrooksReadBarrier) { 78 if (kUseBrooksReadBarrier) { 79 obj->SetReadBarrierPointer(obj); 80 } 81 obj->AssertReadBarrierPointer(); 82 } 83 bytes_allocated = byte_count; 84 usable_size = bytes_allocated; 85 pre_fence_visitor(obj, usable_size); 86 QuasiAtomic::ThreadFenceForConstructor(); 87 } else { 88 obj = TryToAllocate<kInstrumented, false>(self, allocator, byte_count, &bytes_allocated, 89 &usable_size); 90 if (UNLIKELY(obj == nullptr)) { 91 bool is_current_allocator = allocator == GetCurrentAllocator(); 92 obj = AllocateInternalWithGc(self, allocator, byte_count, &bytes_allocated, &usable_size, 93 &klass); 94 if (obj == nullptr) { 95 bool after_is_current_allocator = allocator == GetCurrentAllocator(); 96 // If there is a pending exception, fail the allocation right away since the next one 97 // could cause OOM and abort the runtime. 98 if (!self->IsExceptionPending() && is_current_allocator && !after_is_current_allocator) { 99 // If the allocator changed, we need to restart the allocation. 100 return AllocObject<kInstrumented>(self, klass, byte_count, pre_fence_visitor); 101 } 102 return nullptr; 103 } 104 } 105 DCHECK_GT(bytes_allocated, 0u); 106 DCHECK_GT(usable_size, 0u); 107 obj->SetClass(klass); 108 if (kUseBakerOrBrooksReadBarrier) { 109 if (kUseBrooksReadBarrier) { 110 obj->SetReadBarrierPointer(obj); 111 } 112 obj->AssertReadBarrierPointer(); 113 } 114 if (collector::SemiSpace::kUseRememberedSet && UNLIKELY(allocator == kAllocatorTypeNonMoving)) { 115 // (Note this if statement will be constant folded away for the 116 // fast-path quick entry points.) Because SetClass() has no write 117 // barrier, if a non-moving space allocation, we need a write 118 // barrier as the class pointer may point to the bump pointer 119 // space (where the class pointer is an "old-to-young" reference, 120 // though rare) under the GSS collector with the remembered set 121 // enabled. We don't need this for kAllocatorTypeRosAlloc/DlMalloc 122 // cases because we don't directly allocate into the main alloc 123 // space (besides promotions) under the SS/GSS collector. 124 WriteBarrierField(obj, mirror::Object::ClassOffset(), klass); 125 } 126 pre_fence_visitor(obj, usable_size); 127 new_num_bytes_allocated = 128 static_cast<size_t>(num_bytes_allocated_.FetchAndAddSequentiallyConsistent(bytes_allocated)) 129 + bytes_allocated; 130 } 131 if (kIsDebugBuild && Runtime::Current()->IsStarted()) { 132 CHECK_LE(obj->SizeOf(), usable_size); 133 } 134 // TODO: Deprecate. 135 if (kInstrumented) { 136 if (Runtime::Current()->HasStatsEnabled()) { 137 RuntimeStats* thread_stats = self->GetStats(); 138 ++thread_stats->allocated_objects; 139 thread_stats->allocated_bytes += bytes_allocated; 140 RuntimeStats* global_stats = Runtime::Current()->GetStats(); 141 ++global_stats->allocated_objects; 142 global_stats->allocated_bytes += bytes_allocated; 143 } 144 } else { 145 DCHECK(!Runtime::Current()->HasStatsEnabled()); 146 } 147 if (AllocatorHasAllocationStack(allocator)) { 148 PushOnAllocationStack(self, &obj); 149 } 150 if (kInstrumented) { 151 if (Dbg::IsAllocTrackingEnabled()) { 152 Dbg::RecordAllocation(klass, bytes_allocated); 153 } 154 } else { 155 DCHECK(!Dbg::IsAllocTrackingEnabled()); 156 } 157 // IsConcurrentGc() isn't known at compile time so we can optimize by not checking it for 158 // the BumpPointer or TLAB allocators. This is nice since it allows the entire if statement to be 159 // optimized out. And for the other allocators, AllocatorMayHaveConcurrentGC is a constant since 160 // the allocator_type should be constant propagated. 161 if (AllocatorMayHaveConcurrentGC(allocator) && IsGcConcurrent()) { 162 CheckConcurrentGC(self, new_num_bytes_allocated, &obj); 163 } 164 VerifyObject(obj); 165 self->VerifyStack(); 166 return obj; 167 } 168 169 // The size of a thread-local allocation stack in the number of references. 170 static constexpr size_t kThreadLocalAllocationStackSize = 128; 171 172 inline void Heap::PushOnAllocationStack(Thread* self, mirror::Object** obj) { 173 if (kUseThreadLocalAllocationStack) { 174 if (UNLIKELY(!self->PushOnThreadLocalAllocationStack(*obj))) { 175 PushOnThreadLocalAllocationStackWithInternalGC(self, obj); 176 } 177 } else if (UNLIKELY(!allocation_stack_->AtomicPushBack(*obj))) { 178 PushOnAllocationStackWithInternalGC(self, obj); 179 } 180 } 181 182 template <bool kInstrumented, typename PreFenceVisitor> 183 inline mirror::Object* Heap::AllocLargeObject(Thread* self, mirror::Class** klass, 184 size_t byte_count, 185 const PreFenceVisitor& pre_fence_visitor) { 186 // Save and restore the class in case it moves. 187 StackHandleScope<1> hs(self); 188 auto klass_wrapper = hs.NewHandleWrapper(klass); 189 return AllocObjectWithAllocator<kInstrumented, false, PreFenceVisitor>(self, *klass, byte_count, 190 kAllocatorTypeLOS, 191 pre_fence_visitor); 192 } 193 194 template <const bool kInstrumented, const bool kGrow> 195 inline mirror::Object* Heap::TryToAllocate(Thread* self, AllocatorType allocator_type, 196 size_t alloc_size, size_t* bytes_allocated, 197 size_t* usable_size) { 198 if (allocator_type != kAllocatorTypeTLAB && 199 UNLIKELY(IsOutOfMemoryOnAllocation<kGrow>(allocator_type, alloc_size))) { 200 return nullptr; 201 } 202 mirror::Object* ret; 203 switch (allocator_type) { 204 case kAllocatorTypeBumpPointer: { 205 DCHECK(bump_pointer_space_ != nullptr); 206 alloc_size = RoundUp(alloc_size, space::BumpPointerSpace::kAlignment); 207 ret = bump_pointer_space_->AllocNonvirtual(alloc_size); 208 if (LIKELY(ret != nullptr)) { 209 *bytes_allocated = alloc_size; 210 *usable_size = alloc_size; 211 } 212 break; 213 } 214 case kAllocatorTypeRosAlloc: { 215 if (kInstrumented && UNLIKELY(running_on_valgrind_)) { 216 // If running on valgrind, we should be using the instrumented path. 217 ret = rosalloc_space_->Alloc(self, alloc_size, bytes_allocated, usable_size); 218 } else { 219 DCHECK(!running_on_valgrind_); 220 ret = rosalloc_space_->AllocNonvirtual(self, alloc_size, bytes_allocated, usable_size); 221 } 222 break; 223 } 224 case kAllocatorTypeDlMalloc: { 225 if (kInstrumented && UNLIKELY(running_on_valgrind_)) { 226 // If running on valgrind, we should be using the instrumented path. 227 ret = dlmalloc_space_->Alloc(self, alloc_size, bytes_allocated, usable_size); 228 } else { 229 DCHECK(!running_on_valgrind_); 230 ret = dlmalloc_space_->AllocNonvirtual(self, alloc_size, bytes_allocated, usable_size); 231 } 232 break; 233 } 234 case kAllocatorTypeNonMoving: { 235 ret = non_moving_space_->Alloc(self, alloc_size, bytes_allocated, usable_size); 236 break; 237 } 238 case kAllocatorTypeLOS: { 239 ret = large_object_space_->Alloc(self, alloc_size, bytes_allocated, usable_size); 240 // Note that the bump pointer spaces aren't necessarily next to 241 // the other continuous spaces like the non-moving alloc space or 242 // the zygote space. 243 DCHECK(ret == nullptr || large_object_space_->Contains(ret)); 244 break; 245 } 246 case kAllocatorTypeTLAB: { 247 DCHECK_ALIGNED(alloc_size, space::BumpPointerSpace::kAlignment); 248 if (UNLIKELY(self->TlabSize() < alloc_size)) { 249 const size_t new_tlab_size = alloc_size + kDefaultTLABSize; 250 if (UNLIKELY(IsOutOfMemoryOnAllocation<kGrow>(allocator_type, new_tlab_size))) { 251 return nullptr; 252 } 253 // Try allocating a new thread local buffer, if the allocaiton fails the space must be 254 // full so return nullptr. 255 if (!bump_pointer_space_->AllocNewTlab(self, new_tlab_size)) { 256 return nullptr; 257 } 258 *bytes_allocated = new_tlab_size; 259 } else { 260 *bytes_allocated = 0; 261 } 262 // The allocation can't fail. 263 ret = self->AllocTlab(alloc_size); 264 DCHECK(ret != nullptr); 265 *usable_size = alloc_size; 266 break; 267 } 268 default: { 269 LOG(FATAL) << "Invalid allocator type"; 270 ret = nullptr; 271 } 272 } 273 return ret; 274 } 275 276 inline Heap::AllocationTimer::AllocationTimer(Heap* heap, mirror::Object** allocated_obj_ptr) 277 : heap_(heap), allocated_obj_ptr_(allocated_obj_ptr) { 278 if (kMeasureAllocationTime) { 279 allocation_start_time_ = NanoTime() / kTimeAdjust; 280 } 281 } 282 283 inline Heap::AllocationTimer::~AllocationTimer() { 284 if (kMeasureAllocationTime) { 285 mirror::Object* allocated_obj = *allocated_obj_ptr_; 286 // Only if the allocation succeeded, record the time. 287 if (allocated_obj != nullptr) { 288 uint64_t allocation_end_time = NanoTime() / kTimeAdjust; 289 heap_->total_allocation_time_.FetchAndAddSequentiallyConsistent(allocation_end_time - allocation_start_time_); 290 } 291 } 292 }; 293 294 inline bool Heap::ShouldAllocLargeObject(mirror::Class* c, size_t byte_count) const { 295 // We need to have a zygote space or else our newly allocated large object can end up in the 296 // Zygote resulting in it being prematurely freed. 297 // We can only do this for primitive objects since large objects will not be within the card table 298 // range. This also means that we rely on SetClass not dirtying the object's card. 299 return byte_count >= large_object_threshold_ && c->IsPrimitiveArray(); 300 } 301 302 template <bool kGrow> 303 inline bool Heap::IsOutOfMemoryOnAllocation(AllocatorType allocator_type, size_t alloc_size) { 304 size_t new_footprint = num_bytes_allocated_.LoadSequentiallyConsistent() + alloc_size; 305 if (UNLIKELY(new_footprint > max_allowed_footprint_)) { 306 if (UNLIKELY(new_footprint > growth_limit_)) { 307 return true; 308 } 309 if (!AllocatorMayHaveConcurrentGC(allocator_type) || !IsGcConcurrent()) { 310 if (!kGrow) { 311 return true; 312 } 313 // TODO: Grow for allocation is racy, fix it. 314 VLOG(heap) << "Growing heap from " << PrettySize(max_allowed_footprint_) << " to " 315 << PrettySize(new_footprint) << " for a " << PrettySize(alloc_size) << " allocation"; 316 max_allowed_footprint_ = new_footprint; 317 } 318 } 319 return false; 320 } 321 322 inline void Heap::CheckConcurrentGC(Thread* self, size_t new_num_bytes_allocated, 323 mirror::Object** obj) { 324 if (UNLIKELY(new_num_bytes_allocated >= concurrent_start_bytes_)) { 325 RequestConcurrentGCAndSaveObject(self, obj); 326 } 327 } 328 329 } // namespace gc 330 } // namespace art 331 332 #endif // ART_RUNTIME_GC_HEAP_INL_H_ 333