GC clean up.
Greater use of directories and namespaces.
Fix bugs that cause verify options to fail.
Address numerous other issues:
GC barrier wait occurring holding locks:
GC barrier waits occur when we wait for threads to run the check point function
on themselves. This is happening with the heap bitmap and mutator lock held
meaning that a thread that tries to take either lock exclusively will block
waiting on a thread that is waiting. If this thread is the thread we're waiting
to run the check point then the VM will deadlock.
This deadlock occurred unnoticed as the call to check for wait safety was
removed in: https://googleplex-android-review.googlesource.com/#/c/249423/1.
NewTimingLogger:
Existing timing log states when a split ends but not when it begins. This isn't
good for systrace, in the context of GC it means that races between mutators
and the GC are hard to discover what phase the GC is in, we know what phase it
just finished and derive but that's not ideal.
Support for only 1 discontinuous space:
Code special cases continuous and large object space, rather than assuming we
can have a collection of both.
Sorted atomic stacks:
Used to improve verification performance. Simplify their use and add extra
checks.
Simplify mod-union table abstractions.
Reduce use of std::strings and their associated overhead in hot code.
Make time units of fields explicit.
Reduce confusion that IsAllocSpace is really IsDlMallocSpace.
Make GetTotalMemory (exposed via System) equal to the footprint (as in Dalvik)
rather than the max memory footprint.
Change-Id: Ie87067140fa4499b15edab691fe6565d79599812
diff --git a/src/compiler/dex/quick/arm/call_arm.cc b/src/compiler/dex/quick/arm/call_arm.cc
index 77e09b8..879065f 100644
--- a/src/compiler/dex/quick/arm/call_arm.cc
+++ b/src/compiler/dex/quick/arm/call_arm.cc
@@ -562,7 +562,7 @@
int reg_card_no = AllocTemp();
LIR* branch_over = OpCmpImmBranch(kCondEq, val_reg, 0, NULL);
LoadWordDisp(rARM_SELF, Thread::CardTableOffset().Int32Value(), reg_card_base);
- OpRegRegImm(kOpLsr, reg_card_no, tgt_addr_reg, CardTable::kCardShift);
+ OpRegRegImm(kOpLsr, reg_card_no, tgt_addr_reg, gc::accounting::CardTable::kCardShift);
StoreBaseIndexed(reg_card_base, reg_card_no, reg_card_base, 0,
kUnsignedByte);
LIR* target = NewLIR0(kPseudoTargetLabel);
diff --git a/src/compiler/dex/quick/mips/call_mips.cc b/src/compiler/dex/quick/mips/call_mips.cc
index 9f1d314..ddaf081 100644
--- a/src/compiler/dex/quick/mips/call_mips.cc
+++ b/src/compiler/dex/quick/mips/call_mips.cc
@@ -320,7 +320,7 @@
int reg_card_no = AllocTemp();
LIR* branch_over = OpCmpImmBranch(kCondEq, val_reg, 0, NULL);
LoadWordDisp(rMIPS_SELF, Thread::CardTableOffset().Int32Value(), reg_card_base);
- OpRegRegImm(kOpLsr, reg_card_no, tgt_addr_reg, CardTable::kCardShift);
+ OpRegRegImm(kOpLsr, reg_card_no, tgt_addr_reg, gc::accounting::CardTable::kCardShift);
StoreBaseIndexed(reg_card_base, reg_card_no, reg_card_base, 0,
kUnsignedByte);
LIR* target = NewLIR0(kPseudoTargetLabel);
diff --git a/src/compiler/dex/quick/x86/call_x86.cc b/src/compiler/dex/quick/x86/call_x86.cc
index 1e37b2f..dba0e24 100644
--- a/src/compiler/dex/quick/x86/call_x86.cc
+++ b/src/compiler/dex/quick/x86/call_x86.cc
@@ -213,7 +213,7 @@
int reg_card_no = AllocTemp();
LIR* branch_over = OpCmpImmBranch(kCondEq, val_reg, 0, NULL);
NewLIR2(kX86Mov32RT, reg_card_base, Thread::CardTableOffset().Int32Value());
- OpRegRegImm(kOpLsr, reg_card_no, tgt_addr_reg, CardTable::kCardShift);
+ OpRegRegImm(kOpLsr, reg_card_no, tgt_addr_reg, gc::accounting::CardTable::kCardShift);
StoreBaseIndexed(reg_card_base, reg_card_no, reg_card_base, 0,
kUnsignedByte);
LIR* target = NewLIR0(kPseudoTargetLabel);
diff --git a/src/compiler/driver/compiler_driver.cc b/src/compiler/driver/compiler_driver.cc
index b04e5b1..6050108 100644
--- a/src/compiler/driver/compiler_driver.cc
+++ b/src/compiler/driver/compiler_driver.cc
@@ -31,8 +31,9 @@
#include "oat_file.h"
#include "object_utils.h"
#include "runtime.h"
-#include "gc/card_table-inl.h"
-#include "gc/space.h"
+#include "gc/accounting/card_table-inl.h"
+#include "gc/accounting/heap_bitmap.h"
+#include "gc/space/space.h"
#include "mirror/class_loader.h"
#include "mirror/class-inl.h"
#include "mirror/dex_cache-inl.h"
@@ -761,7 +762,7 @@
// Update image_classes_ with classes for objects created by <clinit> methods.
Thread* self = Thread::Current();
const char* old_cause = self->StartAssertNoThreadSuspension("ImageWriter");
- Heap* heap = Runtime::Current()->GetHeap();
+ gc::Heap* heap = Runtime::Current()->GetHeap();
// TODO: Image spaces only?
WriterMutexLock mu(self, *Locks::heap_bitmap_lock_);
heap->FlushAllocStack();
@@ -1092,7 +1093,7 @@
}
stats_->DirectMethodsToBoot(type);
}
- bool compiling_boot = Runtime::Current()->GetHeap()->GetSpaces().size() == 1;
+ bool compiling_boot = Runtime::Current()->GetHeap()->GetContinuousSpaces().size() == 1;
if (compiling_boot) {
if (support_boot_image_fixup_) {
MethodHelper mh(method);
@@ -1104,7 +1105,7 @@
}
}
} else {
- if (Runtime::Current()->GetHeap()->FindSpaceFromObject(method)->IsImageSpace()) {
+ if (Runtime::Current()->GetHeap()->FindSpaceFromObject(method, false)->IsImageSpace()) {
direct_method = reinterpret_cast<uintptr_t>(method);
}
direct_code = reinterpret_cast<uintptr_t>(method->GetEntryPointFromCompiledCode());
@@ -1382,7 +1383,7 @@
CHECK_NE(self->GetState(), kRunnable);
// Wait for all the worker threads to finish.
- thread_pool_->Wait(self);
+ thread_pool_->Wait(self, true, false);
}
private:
@@ -1915,7 +1916,7 @@
mirror::ClassLoader* class_loader = soa.Decode<mirror::ClassLoader*>(manager->GetClassLoader());
const char* descriptor = manager->GetDexFile()->GetClassDescriptor(class_def);
mirror::Class* klass = manager->GetClassLinker()->FindClass(descriptor, class_loader);
- bool compiling_boot = Runtime::Current()->GetHeap()->GetSpaces().size() == 1;
+ bool compiling_boot = Runtime::Current()->GetHeap()->GetContinuousSpaces().size() == 1;
bool can_init_static_fields = compiling_boot &&
manager->GetCompiler()->IsImageClass(descriptor);
if (klass != NULL) {
@@ -1925,8 +1926,9 @@
// on a second thread the sub-class is initialized (holding its lock) after first initializing
// its parents, whose locks are acquired. This leads to a parent-to-child and a child-to-parent
// lock ordering and consequent potential deadlock.
- static Mutex lock1("Initializer lock", kMonitorLock);
- MutexLock mu(soa.Self(), lock1);
+ // We need to use an ObjectLock due to potential suspension in the interpreting code. Rather
+ // than use a special Object for the purpose we use the Class of java.lang.Class.
+ ObjectLock lock1(soa.Self(), klass->GetClass());
// The lock required to initialize the class.
ObjectLock lock2(soa.Self(), klass);
// Only try to initialize classes that were successfully verified.
diff --git a/src/compiler/driver/compiler_driver_test.cc b/src/compiler/driver/compiler_driver_test.cc
index a7fad6f..abf8a9a 100644
--- a/src/compiler/driver/compiler_driver_test.cc
+++ b/src/compiler/driver/compiler_driver_test.cc
@@ -23,7 +23,7 @@
#include "class_linker.h"
#include "common_test.h"
#include "dex_file.h"
-#include "heap.h"
+#include "gc/heap.h"
#include "mirror/class.h"
#include "mirror/class-inl.h"
#include "mirror/dex_cache-inl.h"
diff --git a/src/compiler/llvm/runtime_support_builder.cc b/src/compiler/llvm/runtime_support_builder.cc
index b4ddb55..2be2ddf 100644
--- a/src/compiler/llvm/runtime_support_builder.cc
+++ b/src/compiler/llvm/runtime_support_builder.cc
@@ -16,7 +16,7 @@
#include "runtime_support_builder.h"
-#include "gc/card_table.h"
+#include "gc/accounting/card_table.h"
#include "ir_builder.h"
#include "monitor.h"
#include "mirror/object.h"
@@ -266,9 +266,11 @@
irb_.getInt8Ty()->getPointerTo(),
kTBAAConstJObject);
Value* target_addr_int = irb_.CreatePtrToInt(target_addr, irb_.getPtrEquivIntTy());
- Value* card_no = irb_.CreateLShr(target_addr_int, irb_.getPtrEquivInt(CardTable::kCardShift));
+ Value* card_no = irb_.CreateLShr(target_addr_int,
+ irb_.getPtrEquivInt(gc::accounting::CardTable::kCardShift));
Value* card_table_entry = irb_.CreateGEP(card_table, card_no);
- irb_.CreateStore(irb_.getInt8(CardTable::kCardDirty), card_table_entry, kTBAARuntimeInfo);
+ irb_.CreateStore(irb_.getInt8(gc::accounting::CardTable::kCardDirty), card_table_entry,
+ kTBAARuntimeInfo);
irb_.CreateBr(bb_cont);
irb_.SetInsertPoint(bb_cont);