Fix and reenable lock dumping in stack dumps.
This patch adds a flag to tell the method verifier not to load
classes when resolving types, so that when we ask the method verifier
to find monitor-enter instructions for stack dumping it doesn't try
to allocate (since the most common cause of stack dumping is SIGQUIT).
We believe that all the classes we care about will be loaded already
anyway, since we're only interested in _held_ locks, and you can only
hold a lock if you've executed the code that leads to the monitor-enter,
and you can't execute the code without loading the relevant classes.
Any not-yet-loaded classes shouldn't be relevant for our purposes.
Also clarify the stack dumps when a thread is starting up; although
strictly speaking a thread might be in the kNative state, it's more
helpful if we also explicitly say that it's still starting up.
Also a few GC log output fixes.
Change-Id: Ibf8519e9bde27838c511eafa5c13734c5bebeab6
diff --git a/src/verifier/method_verifier.cc b/src/verifier/method_verifier.cc
index 41098cb..6611d3c 100644
--- a/src/verifier/method_verifier.cc
+++ b/src/verifier/method_verifier.cc
@@ -295,7 +295,7 @@
uint64_t start_ns = NanoTime();
MethodVerifier verifier(dex_file, dex_cache, class_loader, class_def_idx, code_item, method_idx,
- method, method_access_flags);
+ method, method_access_flags, true);
if (verifier.Verify()) {
// Verification completed, however failures may be pending that didn't cause the verification
// to hard fail.
@@ -331,7 +331,7 @@
const DexFile::CodeItem* code_item, AbstractMethod* method,
uint32_t method_access_flags) {
MethodVerifier verifier(dex_file, dex_cache, class_loader, class_def_idx, code_item,
- dex_method_idx, method, method_access_flags);
+ dex_method_idx, method, method_access_flags, true);
verifier.Verify();
verifier.DumpFailures(os);
os << verifier.info_messages_.str();
@@ -346,15 +346,17 @@
AbstractMethod* method,
uint32_t method_access_flags, uint32_t dex_pc) {
MethodVerifier verifier(dex_file, dex_cache, class_loader, class_def_idx, code_item,
- dex_method_idx, method, method_access_flags);
+ dex_method_idx, method, method_access_flags, true);
verifier.Verify();
return verifier.DescribeVRegs(dex_pc);
}
MethodVerifier::MethodVerifier(const DexFile* dex_file, DexCache* dex_cache,
ClassLoader* class_loader, uint32_t class_def_idx, const DexFile::CodeItem* code_item,
- uint32_t dex_method_idx, AbstractMethod* method, uint32_t method_access_flags)
- : work_insn_idx_(-1),
+ uint32_t dex_method_idx, AbstractMethod* method, uint32_t method_access_flags,
+ bool can_load_classes)
+ : reg_types_(can_load_classes),
+ work_insn_idx_(-1),
dex_method_idx_(dex_method_idx),
foo_method_(method),
method_access_flags_(method_access_flags),
@@ -368,7 +370,8 @@
have_pending_hard_failure_(false),
have_pending_runtime_throw_failure_(false),
new_instance_count_(0),
- monitor_enter_count_(0) {
+ monitor_enter_count_(0),
+ can_load_classes_(can_load_classes) {
}
void MethodVerifier::FindLocksAtDexPc(AbstractMethod* m, uint32_t dex_pc,
@@ -376,7 +379,7 @@
MethodHelper mh(m);
MethodVerifier verifier(&mh.GetDexFile(), mh.GetDexCache(), mh.GetClassLoader(),
mh.GetClassDefIndex(), mh.GetCodeItem(), m->GetDexMethodIndex(),
- m, m->GetAccessFlags());
+ m, m->GetAccessFlags(), false);
verifier.interesting_dex_pc_ = dex_pc;
verifier.monitor_enter_dex_pcs_ = &monitor_enter_dex_pcs;
verifier.FindLocksAtDexPc();