summaryrefslogtreecommitdiff
path: root/runtime/gc/heap-inl.h
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/gc/heap-inl.h')
-rw-r--r--runtime/gc/heap-inl.h22
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);
}