summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--runtime/verifier/method_verifier.cc21
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