summaryrefslogtreecommitdiff
path: root/compiler/optimizing/code_generator_arm.cc
diff options
context:
space:
mode:
authorMathieu Chartier <mathieuc@google.com>2016-11-10 18:05:50 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2016-11-10 18:05:50 +0000
commit977919fbcbfbf0c1c3fa97e51490bc678da646d2 (patch)
tree3e462b1ea5887345ed025b030b0c0a4b71003524 /compiler/optimizing/code_generator_arm.cc
parentee59d46595bb860fea26122f47f8797d2d0fe5f4 (diff)
parentaa474eb597056d21c0b21d353b9b6aa460351d0f (diff)
Merge "Avoid read barriers for inlined check cast"
Diffstat (limited to 'compiler/optimizing/code_generator_arm.cc')
-rw-r--r--compiler/optimizing/code_generator_arm.cc69
1 files changed, 49 insertions, 20 deletions
diff --git a/compiler/optimizing/code_generator_arm.cc b/compiler/optimizing/code_generator_arm.cc
index 25d3855e39..8ca8b8a57b 100644
--- a/compiler/optimizing/code_generator_arm.cc
+++ b/compiler/optimizing/code_generator_arm.cc
@@ -6036,7 +6036,7 @@ static size_t NumberOfInstanceOfTemps(TypeCheckKind type_check_kind) {
return 0;
}
-// InteraceCheck has 3 temps, one for holding the number of interfaces, one for the current
+// Interface case has 3 temps, one for holding the number of interfaces, one for the current
// interface pointer, one for loading the current interface.
// The other checks have one temp for loading the object's class.
static size_t NumberOfCheckCastTemps(TypeCheckKind type_check_kind) {
@@ -6126,7 +6126,11 @@ void InstructionCodeGeneratorARM::VisitInstanceOf(HInstanceOf* instruction) {
Label loop;
__ Bind(&loop);
// /* HeapReference<Class> */ out = out->super_class_
- GenerateReferenceLoadOneRegister(instruction, out_loc, super_offset, maybe_temp_loc);
+ GenerateReferenceLoadOneRegister(instruction,
+ out_loc,
+ super_offset,
+ maybe_temp_loc,
+ kEmitCompilerReadBarrier);
// If `out` is null, we use it for the result, and jump to `done`.
__ CompareAndBranchIfZero(out, &done);
__ cmp(out, ShifterOperand(cls));
@@ -6145,7 +6149,11 @@ void InstructionCodeGeneratorARM::VisitInstanceOf(HInstanceOf* instruction) {
__ cmp(out, ShifterOperand(cls));
__ b(&success, EQ);
// /* HeapReference<Class> */ out = out->super_class_
- GenerateReferenceLoadOneRegister(instruction, out_loc, super_offset, maybe_temp_loc);
+ GenerateReferenceLoadOneRegister(instruction,
+ out_loc,
+ super_offset,
+ maybe_temp_loc,
+ kEmitCompilerReadBarrier);
__ CompareAndBranchIfNonZero(out, &loop);
// If `out` is null, we use it for the result, and jump to `done`.
__ b(&done);
@@ -6164,7 +6172,11 @@ void InstructionCodeGeneratorARM::VisitInstanceOf(HInstanceOf* instruction) {
__ b(&exact_check, EQ);
// Otherwise, we need to check that the object's class is a non-primitive array.
// /* HeapReference<Class> */ out = out->component_type_
- GenerateReferenceLoadOneRegister(instruction, out_loc, component_offset, maybe_temp_loc);
+ GenerateReferenceLoadOneRegister(instruction,
+ out_loc,
+ component_offset,
+ maybe_temp_loc,
+ kEmitCompilerReadBarrier);
// If `out` is null, we use it for the result, and jump to `done`.
__ CompareAndBranchIfZero(out, &done);
__ LoadFromOffset(kLoadUnsignedHalfword, out, out, primitive_offset);
@@ -6284,12 +6296,15 @@ void InstructionCodeGeneratorARM::VisitCheckCast(HCheckCast* instruction) {
const uint32_t object_array_data_offset =
mirror::Array::DataOffset(kHeapReferenceSize).Uint32Value();
- bool is_type_check_slow_path_fatal =
- (type_check_kind == TypeCheckKind::kExactCheck ||
- type_check_kind == TypeCheckKind::kAbstractClassCheck ||
- type_check_kind == TypeCheckKind::kClassHierarchyCheck ||
- type_check_kind == TypeCheckKind::kArrayObjectCheck) &&
- !instruction->CanThrowIntoCatchBlock();
+ bool is_type_check_slow_path_fatal = false;
+ if (!kEmitCompilerReadBarrier) {
+ is_type_check_slow_path_fatal =
+ (type_check_kind == TypeCheckKind::kExactCheck ||
+ type_check_kind == TypeCheckKind::kAbstractClassCheck ||
+ type_check_kind == TypeCheckKind::kClassHierarchyCheck ||
+ type_check_kind == TypeCheckKind::kArrayObjectCheck) &&
+ !instruction->CanThrowIntoCatchBlock();
+ }
SlowPathCodeARM* type_check_slow_path =
new (GetGraph()->GetArena()) TypeCheckSlowPathARM(instruction,
is_type_check_slow_path_fatal);
@@ -6310,7 +6325,7 @@ void InstructionCodeGeneratorARM::VisitCheckCast(HCheckCast* instruction) {
obj_loc,
class_offset,
maybe_temp2_loc,
- kEmitCompilerReadBarrier);
+ /*emit_read_barrier*/ false);
__ cmp(temp, ShifterOperand(cls));
// Jump to slow path for throwing the exception or doing a
@@ -6326,14 +6341,18 @@ void InstructionCodeGeneratorARM::VisitCheckCast(HCheckCast* instruction) {
obj_loc,
class_offset,
maybe_temp2_loc,
- kEmitCompilerReadBarrier);
+ /*emit_read_barrier*/ false);
// If the class is abstract, we eagerly fetch the super class of the
// object to avoid doing a comparison we know will fail.
Label loop;
__ Bind(&loop);
// /* HeapReference<Class> */ temp = temp->super_class_
- GenerateReferenceLoadOneRegister(instruction, temp_loc, super_offset, maybe_temp2_loc);
+ GenerateReferenceLoadOneRegister(instruction,
+ temp_loc,
+ super_offset,
+ maybe_temp2_loc,
+ /*emit_read_barrier*/ false);
// If the class reference currently in `temp` is null, jump to the slow path to throw the
// exception.
@@ -6352,7 +6371,7 @@ void InstructionCodeGeneratorARM::VisitCheckCast(HCheckCast* instruction) {
obj_loc,
class_offset,
maybe_temp2_loc,
- kEmitCompilerReadBarrier);
+ /*emit_read_barrier*/ false);
// Walk over the class hierarchy to find a match.
Label loop;
@@ -6361,7 +6380,11 @@ void InstructionCodeGeneratorARM::VisitCheckCast(HCheckCast* instruction) {
__ b(&done, EQ);
// /* HeapReference<Class> */ temp = temp->super_class_
- GenerateReferenceLoadOneRegister(instruction, temp_loc, super_offset, maybe_temp2_loc);
+ GenerateReferenceLoadOneRegister(instruction,
+ temp_loc,
+ super_offset,
+ maybe_temp2_loc,
+ /*emit_read_barrier*/ false);
// If the class reference currently in `temp` is null, jump to the slow path to throw the
// exception.
@@ -6378,7 +6401,7 @@ void InstructionCodeGeneratorARM::VisitCheckCast(HCheckCast* instruction) {
obj_loc,
class_offset,
maybe_temp2_loc,
- kEmitCompilerReadBarrier);
+ /*emit_read_barrier*/ false);
// Do an exact check.
__ cmp(temp, ShifterOperand(cls));
@@ -6386,7 +6409,11 @@ void InstructionCodeGeneratorARM::VisitCheckCast(HCheckCast* instruction) {
// Otherwise, we need to check that the object's class is a non-primitive array.
// /* HeapReference<Class> */ temp = temp->component_type_
- GenerateReferenceLoadOneRegister(instruction, temp_loc, component_offset, maybe_temp2_loc);
+ GenerateReferenceLoadOneRegister(instruction,
+ temp_loc,
+ component_offset,
+ maybe_temp2_loc,
+ /*emit_read_barrier*/ false);
// If the component type is null, jump to the slow path to throw the exception.
__ CompareAndBranchIfZero(temp, type_check_slow_path->GetEntryLabel());
// Otherwise,the object is indeed an array, jump to label `check_non_primitive_component_type`
@@ -6730,9 +6757,11 @@ void InstructionCodeGeneratorARM::HandleBitwiseOperation(HBinaryOperation* instr
void InstructionCodeGeneratorARM::GenerateReferenceLoadOneRegister(HInstruction* instruction,
Location out,
uint32_t offset,
- Location maybe_temp) {
+ Location maybe_temp,
+ bool emit_read_barrier) {
Register out_reg = out.AsRegister<Register>();
- if (kEmitCompilerReadBarrier) {
+ if (emit_read_barrier) {
+ CHECK(kEmitCompilerReadBarrier);
DCHECK(maybe_temp.IsRegister()) << maybe_temp;
if (kUseBakerReadBarrier) {
// Load with fast path based Baker's read barrier.
@@ -6766,7 +6795,7 @@ void InstructionCodeGeneratorARM::GenerateReferenceLoadTwoRegisters(HInstruction
Register out_reg = out.AsRegister<Register>();
Register obj_reg = obj.AsRegister<Register>();
if (emit_read_barrier) {
- DCHECK(kEmitCompilerReadBarrier);
+ CHECK(kEmitCompilerReadBarrier);
if (kUseBakerReadBarrier) {
DCHECK(maybe_temp.IsRegister()) << maybe_temp;
// Load with fast path based Baker's read barrier.