Improve quick codegen for aput-object.
1) don't type check known null.
2) if we know types in verify don't check at runtime.
3) if we're runtime checking then move all the code out-of-line.
Also, don't set up a callee-save frame for check-cast, do an instance-of test
then throw an exception if that fails.
Tidy quick entry point of Ldivmod to Lmod which it is on x86 and mips.
Fix monitor-enter/exit NPE for MIPS.
Fix benign bug in mirror::Class::CannotBeAssignedFromOtherTypes, a byte[]
cannot be assigned to from other types.
Change-Id: I9cb3859ec70cca71ed79331ec8df5bec969d6745
diff --git a/compiler/dex/quick/mir_to_lir.cc b/compiler/dex/quick/mir_to_lir.cc
index 66ece2c..2b26c3d 100644
--- a/compiler/dex/quick/mir_to_lir.cc
+++ b/compiler/dex/quick/mir_to_lir.cc
@@ -338,22 +338,35 @@
GenArrayGet(opt_flags, kSignedHalf, rl_src[0], rl_src[1], rl_dest, 1);
break;
case Instruction::APUT_WIDE:
- GenArrayPut(opt_flags, kLong, rl_src[1], rl_src[2], rl_src[0], 3);
+ GenArrayPut(opt_flags, kLong, rl_src[1], rl_src[2], rl_src[0], 3, false);
break;
case Instruction::APUT:
- GenArrayPut(opt_flags, kWord, rl_src[1], rl_src[2], rl_src[0], 2);
+ GenArrayPut(opt_flags, kWord, rl_src[1], rl_src[2], rl_src[0], 2, false);
break;
- case Instruction::APUT_OBJECT:
- GenArrayObjPut(opt_flags, rl_src[1], rl_src[2], rl_src[0], 2);
+ case Instruction::APUT_OBJECT: {
+ bool is_null = mir_graph_->IsConstantNullRef(rl_src[0]);
+ bool is_safe = is_null; // Always safe to store null.
+ if (!is_safe) {
+ // Check safety from verifier type information.
+ const MethodReference mr(cu_->dex_file, cu_->method_idx);
+ is_safe = cu_->compiler_driver->IsSafeCast(mr, mir->offset);
+ }
+ if (is_null || is_safe) {
+ // Store of constant null doesn't require an assignability test and can be generated inline
+ // without fixed register usage or a card mark.
+ GenArrayPut(opt_flags, kWord, rl_src[1], rl_src[2], rl_src[0], 2, !is_null);
+ } else {
+ GenArrayObjPut(opt_flags, rl_src[1], rl_src[2], rl_src[0]);
+ }
break;
+ }
case Instruction::APUT_SHORT:
case Instruction::APUT_CHAR:
- GenArrayPut(opt_flags, kUnsignedHalf, rl_src[1], rl_src[2], rl_src[0], 1);
+ GenArrayPut(opt_flags, kUnsignedHalf, rl_src[1], rl_src[2], rl_src[0], 1, false);
break;
case Instruction::APUT_BYTE:
case Instruction::APUT_BOOLEAN:
- GenArrayPut(opt_flags, kUnsignedByte, rl_src[1], rl_src[2],
- rl_src[0], 0);
+ GenArrayPut(opt_flags, kUnsignedByte, rl_src[1], rl_src[2], rl_src[0], 0, false);
break;
case Instruction::IGET_OBJECT: