diff options
Diffstat (limited to 'runtime/gc/heap-inl.h')
| -rw-r--r-- | runtime/gc/heap-inl.h | 22 |
1 files changed, 17 insertions, 5 deletions
diff --git a/runtime/gc/heap-inl.h b/runtime/gc/heap-inl.h index 3101c68599..9d2f6d1238 100644 --- a/runtime/gc/heap-inl.h +++ b/runtime/gc/heap-inl.h @@ -48,11 +48,20 @@ inline mirror::Object* Heap::AllocObjectWithAllocator(Thread* self, mirror::Clas } // Need to check that we arent the large object allocator since the large object allocation code // path this function. If we didn't check we would have an infinite loop. + mirror::Object* obj; if (kCheckLargeObject && UNLIKELY(ShouldAllocLargeObject(klass, byte_count))) { - return AllocLargeObject<kInstrumented, PreFenceVisitor>(self, klass, byte_count, - pre_fence_visitor); + obj = AllocLargeObject<kInstrumented, PreFenceVisitor>(self, &klass, byte_count, + pre_fence_visitor); + if (obj != nullptr) { + return obj; + } else { + // There should be an OOM exception, since we are retrying, clear it. + self->ClearException(); + } + // If the large object allocation failed, try to use the normal spaces (main space, + // non moving space). This can happen if there is significant virtual address space + // fragmentation. } - mirror::Object* obj; AllocationTimer alloc_timer(this, &obj); size_t bytes_allocated; size_t usable_size; @@ -171,10 +180,13 @@ inline void Heap::PushOnAllocationStack(Thread* self, mirror::Object** obj) { } template <bool kInstrumented, typename PreFenceVisitor> -inline mirror::Object* Heap::AllocLargeObject(Thread* self, mirror::Class* klass, +inline mirror::Object* Heap::AllocLargeObject(Thread* self, mirror::Class** klass, size_t byte_count, const PreFenceVisitor& pre_fence_visitor) { - return AllocObjectWithAllocator<kInstrumented, false, PreFenceVisitor>(self, klass, byte_count, + // Save and restore the class in case it moves. + StackHandleScope<1> hs(self); + auto klass_wrapper = hs.NewHandleWrapper(klass); + return AllocObjectWithAllocator<kInstrumented, false, PreFenceVisitor>(self, *klass, byte_count, kAllocatorTypeLOS, pre_fence_visitor); } |