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/arm/codegen_arm.h b/compiler/dex/quick/arm/codegen_arm.h
index b75661c..aa5782b 100644
--- a/compiler/dex/quick/arm/codegen_arm.h
+++ b/compiler/dex/quick/arm/codegen_arm.h
@@ -89,12 +89,10 @@
// Required for target - Dalvik-level generators.
void GenArithImmOpLong(Instruction::Code opcode, RegLocation rl_dest,
RegLocation rl_src1, RegLocation rl_src2);
- void GenArrayObjPut(int opt_flags, RegLocation rl_array, RegLocation rl_index,
- RegLocation rl_src, int scale);
void GenArrayGet(int opt_flags, OpSize size, RegLocation rl_array,
RegLocation rl_index, RegLocation rl_dest, int scale);
- void GenArrayPut(int opt_flags, OpSize size, RegLocation rl_array,
- RegLocation rl_index, RegLocation rl_src, int scale);
+ void GenArrayPut(int opt_flags, OpSize size, RegLocation rl_array, RegLocation rl_index,
+ RegLocation rl_src, int scale, bool card_mark);
void GenShiftImmOpLong(Instruction::Code opcode, RegLocation rl_dest,
RegLocation rl_src1, RegLocation rl_shift);
void GenMulLong(RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2);
diff --git a/compiler/dex/quick/arm/int_arm.cc b/compiler/dex/quick/arm/int_arm.cc
index 6d11b03..b1772fd 100644
--- a/compiler/dex/quick/arm/int_arm.cc
+++ b/compiler/dex/quick/arm/int_arm.cc
@@ -771,7 +771,7 @@
* Generate array load
*/
void ArmMir2Lir::GenArrayGet(int opt_flags, OpSize size, RegLocation rl_array,
- RegLocation rl_index, RegLocation rl_dest, int scale) {
+ RegLocation rl_index, RegLocation rl_dest, int scale) {
RegisterClass reg_class = oat_reg_class_by_size(size);
int len_offset = mirror::Array::LengthOffset().Int32Value();
int data_offset;
@@ -861,13 +861,13 @@
*
*/
void ArmMir2Lir::GenArrayPut(int opt_flags, OpSize size, RegLocation rl_array,
- RegLocation rl_index, RegLocation rl_src, int scale) {
+ RegLocation rl_index, RegLocation rl_src, int scale, bool card_mark) {
RegisterClass reg_class = oat_reg_class_by_size(size);
int len_offset = mirror::Array::LengthOffset().Int32Value();
- int data_offset;
bool constant_index = rl_index.is_const;
- if (rl_src.wide) {
+ int data_offset;
+ if (size == kLong || size == kDouble) {
data_offset = mirror::Array::DataOffset(sizeof(int64_t)).Int32Value();
} else {
data_offset = mirror::Array::DataOffset(sizeof(int32_t)).Int32Value();
@@ -943,68 +943,12 @@
if (!constant_index) {
FreeTemp(reg_ptr);
}
-}
-
-/*
- * Generate array store
- *
- */
-void ArmMir2Lir::GenArrayObjPut(int opt_flags, RegLocation rl_array,
- RegLocation rl_index, RegLocation rl_src, int scale) {
- int len_offset = mirror::Array::LengthOffset().Int32Value();
- int data_offset = mirror::Array::DataOffset(sizeof(mirror::Object*)).Int32Value();
-
- FlushAllRegs(); // Use explicit registers
- LockCallTemps();
-
- int r_value = TargetReg(kArg0); // Register holding value
- int r_array_class = TargetReg(kArg1); // Register holding array's Class
- int r_array = TargetReg(kArg2); // Register holding array
- int r_index = TargetReg(kArg3); // Register holding index into array
-
- LoadValueDirectFixed(rl_array, r_array); // Grab array
- LoadValueDirectFixed(rl_src, r_value); // Grab value
- LoadValueDirectFixed(rl_index, r_index); // Grab index
-
- GenNullCheck(rl_array.s_reg_low, r_array, opt_flags); // NPE?
-
- // Store of null?
- LIR* null_value_check = OpCmpImmBranch(kCondEq, r_value, 0, NULL);
-
- // Get the array's class.
- LoadWordDisp(r_array, mirror::Object::ClassOffset().Int32Value(), r_array_class);
- CallRuntimeHelperRegReg(QUICK_ENTRYPOINT_OFFSET(pCanPutArrayElement), r_value,
- r_array_class, true);
- // Redo LoadValues in case they didn't survive the call.
- LoadValueDirectFixed(rl_array, r_array); // Reload array
- LoadValueDirectFixed(rl_index, r_index); // Reload index
- LoadValueDirectFixed(rl_src, r_value); // Reload value
- r_array_class = INVALID_REG;
-
- // Branch here if value to be stored == null
- LIR* target = NewLIR0(kPseudoTargetLabel);
- null_value_check->target = target;
-
- bool needs_range_check = (!(opt_flags & MIR_IGNORE_RANGE_CHECK));
- int reg_len = INVALID_REG;
- if (needs_range_check) {
- reg_len = TargetReg(kArg1);
- LoadWordDisp(r_array, len_offset, reg_len); // Get len
- }
- /* r_ptr -> array data */
- int r_ptr = AllocTemp();
- OpRegRegImm(kOpAdd, r_ptr, r_array, data_offset);
- if (needs_range_check) {
- GenRegRegCheck(kCondCs, r_index, reg_len, kThrowArrayBounds);
- }
- StoreBaseIndexed(r_ptr, r_index, r_value, scale, kWord);
- FreeTemp(r_ptr);
- FreeTemp(r_index);
- if (!mir_graph_->IsConstantNullRef(rl_src)) {
- MarkGCCard(r_value, r_array);
+ if (card_mark) {
+ MarkGCCard(rl_src.low_reg, rl_array.low_reg);
}
}
+
void ArmMir2Lir::GenShiftImmOpLong(Instruction::Code opcode,
RegLocation rl_dest, RegLocation rl_src, RegLocation rl_shift) {
rl_src = LoadValueWide(rl_src, kCoreReg);