Don't allow allocating finalizable objects during transactions.
It doesn't make sense to allocate finalizable objects during a
transcation since they will never get finalized without a started
runtime.
Before StatusInitialized in core.host.oatdump.txt: 3564
After StatusInitialized in core.host.oatdump.txt: 3564
Bug: 14078487
Change-Id: I7070536f7bb87bfc691d4268bd39a3eca492f48e
diff --git a/runtime/interpreter/interpreter_goto_table_impl.cc b/runtime/interpreter/interpreter_goto_table_impl.cc
index d0bb001..74b7c42 100644
--- a/runtime/interpreter/interpreter_goto_table_impl.cc
+++ b/runtime/interpreter/interpreter_goto_table_impl.cc
@@ -496,7 +496,7 @@
}
HANDLE_INSTRUCTION_END();
- HANDLE_INSTRUCTION_START(ARRAY_LENGTH) {
+ HANDLE_INSTRUCTION_START(ARRAY_LENGTH) {
Object* array = shadow_frame.GetVRegReference(inst->VRegB_12x(inst_data));
if (UNLIKELY(array == NULL)) {
ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
@@ -509,12 +509,20 @@
HANDLE_INSTRUCTION_END();
HANDLE_INSTRUCTION_START(NEW_INSTANCE) {
+ Runtime* runtime = Runtime::Current();
Object* obj = AllocObjectFromCode<do_access_check, true>(
inst->VRegB_21c(), shadow_frame.GetMethod(), self,
- Runtime::Current()->GetHeap()->GetCurrentAllocator());
+ runtime->GetHeap()->GetCurrentAllocator());
if (UNLIKELY(obj == NULL)) {
HANDLE_PENDING_EXCEPTION();
} else {
+ // Don't allow finalizable objects to be allocated during a transaction since these can't be
+ // finalized without a started runtime.
+ if (transaction_active && obj->GetClass()->IsFinalizable()) {
+ AbortTransaction(self, "Allocating finalizable object in transcation: %s",
+ PrettyTypeOf(obj).c_str());
+ HANDLE_PENDING_EXCEPTION();
+ }
shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), obj);
ADVANCE(2);
}