Home | History | Annotate | Download | only in gc
      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