diff options
| author | 2014-09-18 13:16:38 -0700 | |
|---|---|---|
| committer | 2014-09-29 08:12:44 -0700 | |
| commit | cb3c08fe9c733e477776dcc0d0fa5a3cf0053aa7 (patch) | |
| tree | 518abbf5fa2dc8488ddb7f31b7941d41dc00f002 | |
| parent | c70535b4f9f1ff3e3da451734bb7d9601012ccc1 (diff) | |
ART: Do a pre-pass for monitor_enter dex pc search
In case the method does not have any monitor_enter instructions,
it is unnecessary to run the full verifier. Speeds up stack dumps
and works around b/17514582.
Bug: 17514582
Change-Id: I5201bfbb9fb6cad49596b4c72e71983b58d9f20c
| -rw-r--r-- | runtime/verifier/method_verifier.cc | 21 |
1 files changed, 21 insertions, 0 deletions
diff --git a/runtime/verifier/method_verifier.cc b/runtime/verifier/method_verifier.cc index 467390662f..02aea1970f 100644 --- a/runtime/verifier/method_verifier.cc +++ b/runtime/verifier/method_verifier.cc @@ -379,10 +379,31 @@ void MethodVerifier::FindLocksAtDexPc(mirror::ArtMethod* m, uint32_t dex_pc, verifier.FindLocksAtDexPc(); } +static bool HasMonitorEnterInstructions(const DexFile::CodeItem* const code_item) { + const Instruction* inst = Instruction::At(code_item->insns_); + + uint32_t insns_size = code_item->insns_size_in_code_units_; + for (uint32_t dex_pc = 0; dex_pc < insns_size;) { + if (inst->Opcode() == Instruction::MONITOR_ENTER) { + return true; + } + + dex_pc += inst->SizeInCodeUnits(); + inst = inst->Next(); + } + + return false; +} + void MethodVerifier::FindLocksAtDexPc() { CHECK(monitor_enter_dex_pcs_ != nullptr); CHECK(code_item_ != nullptr); // This only makes sense for methods with code. + // Quick check whether there are any monitor_enter instructions at all. + if (!HasMonitorEnterInstructions(code_item_)) { + return; + } + // Strictly speaking, we ought to be able to get away with doing a subset of the full method // verification. In practice, the phase we want relies on data structures set up by all the // earlier passes, so we just run the full method verification and bail out early when we've |