summaryrefslogtreecommitdiffstats
path: root/src/verifier/method_verifier.cc
diff options
context:
space:
mode:
authorIan Rogers <irogers@google.com>2013-06-05 08:33:27 -0700
committerIan Rogers <irogers@google.com>2013-06-05 08:33:27 -0700
commitfae370a044f5817f69937cccfd2d12a16b374266 (patch)
tree60af2a03b19e9bcca149e0519504da134d17f9ed /src/verifier/method_verifier.cc
parent1b1e8da7287e199533bf63d72f16fdff99fe7f8e (diff)
downloadandroid_art-fae370a044f5817f69937cccfd2d12a16b374266.tar.gz
android_art-fae370a044f5817f69937cccfd2d12a16b374266.tar.bz2
android_art-fae370a044f5817f69937cccfd2d12a16b374266.zip
Don't apply instance-of peephole when vDest == vSrc.
Bug: 9284898. Also statistic to show check-cast ellision use. Fix bug where the check-cast ellision was using wrong dex pc. Avoid a use of DecodedInstruction. Other formatting clean-up. Change-Id: Ibf67941a24148b615896d0be6f2f29ce5034e53a
Diffstat (limited to 'src/verifier/method_verifier.cc')
-rw-r--r--src/verifier/method_verifier.cc63
1 files changed, 32 insertions, 31 deletions
diff --git a/src/verifier/method_verifier.cc b/src/verifier/method_verifier.cc
index 519de80db8..9d4b902cf0 100644
--- a/src/verifier/method_verifier.cc
+++ b/src/verifier/method_verifier.cc
@@ -1777,31 +1777,33 @@ bool MethodVerifier::CodeFlowVerifyInstruction(uint32_t* start_guess) {
/* Check for peep-hole pattern of:
* ...;
- * instance-of vX, vO, T;
- * ifXXX vX, b ;
+ * instance-of vX, vY, T;
+ * ifXXX vX, label ;
* ...;
- * b: INST;
+ * label:
* ...;
- * and sharpen the type for either the fall-through or the branch case.
+ * and sharpen the type of vY to be type T.
+ * Note, this pattern can't be if:
+ * - if there are other branches to this branch,
+ * - when vX == vY.
*/
- if (!CurrentInsnFlags()->IsBranchTarget()) {
- if ((Instruction::INSTANCE_OF == prev_inst->Opcode())
- && (inst->VRegA_21t() == prev_inst->VRegA_22c())) {
- // Check that the we are not attempting conversion to interface types,
- // which is not done because of the multiple inheritance implications.
- const RegType& cast_type =
- ResolveClassAndCheckAccess(prev_inst->VRegC_22c());
-
- if(!cast_type.IsUnresolvedTypes() && !cast_type.GetClass()->IsInterface()) {
- if (inst->Opcode() == Instruction::IF_EQZ) {
- fallthrough_line.reset(new RegisterLine(code_item_->registers_size_, this));
- fallthrough_line->CopyFromLine(work_line_.get());
- fallthrough_line->SetRegisterType(prev_inst->VRegB_22c(), cast_type);
- } else {
- branch_line.reset(new RegisterLine(code_item_->registers_size_, this));
- branch_line->CopyFromLine(work_line_.get());
- branch_line->SetRegisterType(prev_inst->VRegB_22c(), cast_type);
- }
+ if (!CurrentInsnFlags()->IsBranchTarget() &&
+ (Instruction::INSTANCE_OF == prev_inst->Opcode()) &&
+ (inst->VRegA_21t() == prev_inst->VRegA_22c()) &&
+ (prev_inst->VRegA_22c() != prev_inst->VRegB_22c())) {
+ // Check that the we are not attempting conversion to interface types,
+ // which is not done because of the multiple inheritance implications.
+ const RegType& cast_type = ResolveClassAndCheckAccess(prev_inst->VRegC_22c());
+
+ if(!cast_type.IsUnresolvedTypes() && !cast_type.GetClass()->IsInterface()) {
+ if (inst->Opcode() == Instruction::IF_EQZ) {
+ fallthrough_line.reset(new RegisterLine(code_item_->registers_size_, this));
+ fallthrough_line->CopyFromLine(work_line_.get());
+ fallthrough_line->SetRegisterType(prev_inst->VRegB_22c(), cast_type);
+ } else {
+ branch_line.reset(new RegisterLine(code_item_->registers_size_, this));
+ branch_line->CopyFromLine(work_line_.get());
+ branch_line->SetRegisterType(prev_inst->VRegB_22c(), cast_type);
}
}
}
@@ -3304,24 +3306,22 @@ MethodVerifier::MethodSafeCastSet* MethodVerifier::GenerateSafeCastSet() {
return NULL;
}
UniquePtr<MethodSafeCastSet> mscs;
- uint32_t dex_pc = 0;
const Instruction* inst = Instruction::At(code_item_->insns_);
const Instruction* end = Instruction::At(code_item_->insns_ +
- code_item_->insns_size_in_code_units_);
+ code_item_->insns_size_in_code_units_);
for (; inst < end; inst = inst->Next()) {
- if( Instruction::CHECK_CAST != inst->Opcode() )
+ if (Instruction::CHECK_CAST != inst->Opcode()) {
continue;
-
+ }
+ uint32_t dex_pc = inst->GetDexPc(code_item_->insns_);
RegisterLine* line = reg_table_.GetLine(dex_pc);
- DecodedInstruction dec_insn(inst);
- const RegType& reg_type(line->GetRegisterType(dec_insn.vA));
- const RegType& cast_type = ResolveClassAndCheckAccess(dec_insn.vB);
+ const RegType& reg_type(line->GetRegisterType(inst->VRegA_21c()));
+ const RegType& cast_type = ResolveClassAndCheckAccess(inst->VRegB_21c());
if (cast_type.IsAssignableFrom(reg_type)) {
if (mscs.get() == NULL) {
mscs.reset(new MethodSafeCastSet());
}
- uint32_t dex_pc = inst->GetDexPc(code_item_->insns_);
mscs->insert(dex_pc);
}
}
@@ -3511,7 +3511,8 @@ void MethodVerifier::SetDexGcMap(CompilerDriver::MethodReference ref,
}
-void MethodVerifier::SetSafeCastMap(CompilerDriver::MethodReference ref, const MethodSafeCastSet* cast_set) {
+void MethodVerifier::SetSafeCastMap(CompilerDriver::MethodReference ref,
+ const MethodSafeCastSet* cast_set) {
MutexLock mu(Thread::Current(), *safecast_map_lock_);
SafeCastMap::iterator it = safecast_map_->find(ref);
if (it != safecast_map_->end()) {