There was a problem where we would call SetStatus when we had an OOM
error. This results in attempting to find the ExceptionInInitializer
class which if not loaded does more allocations resulting in an
infinite loop.
Also some cleanup addressing other comments.
Bug:
16082350
(cherry picked from commit
fd22d5bada15d95b5ea8ab5a4dda39077e1a54ee)
Change-Id: Ie291eb0f52ba9c63f24591fae691dd9f393e6ccb
CardTable::CardTable(MemMap* mem_map, byte* biased_begin, size_t offset)
: mem_map_(mem_map), biased_begin_(biased_begin), offset_(offset) {
- byte* __attribute__((unused)) begin = mem_map_->Begin() + offset_;
- byte* __attribute__((unused)) end = mem_map_->End();
}
void CardTable::ClearSpaceCards(space::ContinuousSpace* space) {
// If we have a thread local allocation we don't need to update bytes allocated.
if (allocator == kAllocatorTypeTLAB && byte_count <= self->TlabSize()) {
obj = self->AllocTlab(byte_count);
+ DCHECK(obj != nullptr) << "AllocTlab can't fail";
obj->SetClass(klass);
if (kUseBakerOrBrooksReadBarrier) {
if (kUseBrooksReadBarrier) {
obj->AssertReadBarrierPointer();
}
bytes_allocated = byte_count;
- pre_fence_visitor(obj, bytes_allocated);
+ usable_size = bytes_allocated;
+ pre_fence_visitor(obj, usable_size);
QuasiAtomic::ThreadFenceForConstructor();
} else {
obj = TryToAllocate<kInstrumented, false>(self, allocator, byte_count, &bytes_allocated,
WriteBarrierField(obj, mirror::Object::ClassOffset(), klass);
}
pre_fence_visitor(obj, usable_size);
- if (kIsDebugBuild && Runtime::Current()->IsStarted()) {
- CHECK_LE(obj->SizeOf(), usable_size);
- }
new_num_bytes_allocated =
static_cast<size_t>(num_bytes_allocated_.FetchAndAddSequentiallyConsistent(bytes_allocated))
+ bytes_allocated;
}
+ if (kIsDebugBuild && Runtime::Current()->IsStarted()) {
+ CHECK_LE(obj->SizeOf(), usable_size);
+ }
// TODO: Deprecate.
if (kInstrumented) {
if (Runtime::Current()->HasStatsEnabled()) {
Handle<mirror::ArtMethod> old_throw_method(hs.NewHandle(old_throw_location.GetMethod()));
uint32_t old_throw_dex_pc = old_throw_location.GetDexPc();
bool is_exception_reported = self->IsExceptionReportedToInstrumentation();
- // clear exception to call FindSystemClass
- self->ClearException();
- ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
- Class* eiie_class = class_linker->FindSystemClass(self,
- "Ljava/lang/ExceptionInInitializerError;");
- CHECK(!self->IsExceptionPending());
-
- // Only verification errors, not initialization problems, should set a verify error.
- // This is to ensure that ThrowEarlierClassFailure will throw NoClassDefFoundError in that case.
- Class* exception_class = old_exception->GetClass();
- if (!eiie_class->IsAssignableFrom(exception_class)) {
- SetVerifyErrorClass(exception_class);
+ Class* eiie_class;
+ // Do't attempt to use FindClass if we have an OOM error since this can try to do more
+ // allocations and may cause infinite loops.
+ if (old_exception.Get() == nullptr ||
+ old_exception->GetClass()->GetDescriptor() != "Ljava/lang/OutOfMemoryError;") {
+ // Clear exception to call FindSystemClass.
+ self->ClearException();
+ eiie_class = Runtime::Current()->GetClassLinker()->FindSystemClass(
+ self, "Ljava/lang/ExceptionInInitializerError;");
+ CHECK(!self->IsExceptionPending());
+ // Only verification errors, not initialization problems, should set a verify error.
+ // This is to ensure that ThrowEarlierClassFailure will throw NoClassDefFoundError in that case.
+ Class* exception_class = old_exception->GetClass();
+ if (!eiie_class->IsAssignableFrom(exception_class)) {
+ SetVerifyErrorClass(exception_class);
+ }
}
// Restore exception.