diff options
Diffstat (limited to 'compiler/optimizing')
| -rw-r--r-- | compiler/optimizing/code_generator_arm.cc | 7 | ||||
| -rw-r--r-- | compiler/optimizing/code_generator_arm64.cc | 7 | ||||
| -rw-r--r-- | compiler/optimizing/code_generator_arm_vixl.cc | 33 | ||||
| -rw-r--r-- | compiler/optimizing/code_generator_x86.cc | 28 | ||||
| -rw-r--r-- | compiler/optimizing/code_generator_x86_64.cc | 25 |
5 files changed, 61 insertions, 39 deletions
diff --git a/compiler/optimizing/code_generator_arm.cc b/compiler/optimizing/code_generator_arm.cc index c6363d1708..7c3a2c6b6e 100644 --- a/compiler/optimizing/code_generator_arm.cc +++ b/compiler/optimizing/code_generator_arm.cc @@ -6490,12 +6490,9 @@ void InstructionCodeGeneratorARM::VisitCheckCast(HCheckCast* instruction) { iftable_offset, maybe_temp2_loc, kWithoutReadBarrier); - // Null iftable means it is empty and will always fail the check. - __ CompareAndBranchIfZero(temp, type_check_slow_path->GetEntryLabel()); - - // Loop through the iftable and check if any class matches. + // Iftable is never null. __ ldr(maybe_temp2_loc.AsRegister<Register>(), Address(temp, array_length_offset)); - + // Loop through the iftable and check if any class matches. Label start_loop; __ Bind(&start_loop); __ CompareAndBranchIfZero(maybe_temp2_loc.AsRegister<Register>(), diff --git a/compiler/optimizing/code_generator_arm64.cc b/compiler/optimizing/code_generator_arm64.cc index 4ab6065819..6ec9c910ec 100644 --- a/compiler/optimizing/code_generator_arm64.cc +++ b/compiler/optimizing/code_generator_arm64.cc @@ -3802,12 +3802,9 @@ void InstructionCodeGeneratorARM64::VisitCheckCast(HCheckCast* instruction) { iftable_offset, maybe_temp2_loc, kWithoutReadBarrier); - // Null iftable means it is empty and will always fail the check. - __ Cbz(temp, type_check_slow_path->GetEntryLabel()); - - // Loop through the iftable and check if any class matches. + // Iftable is never null. __ Ldr(WRegisterFrom(maybe_temp2_loc), HeapOperand(temp.W(), array_length_offset)); - + // Loop through the iftable and check if any class matches. vixl::aarch64::Label start_loop; __ Bind(&start_loop); __ Cbz(WRegisterFrom(maybe_temp2_loc), type_check_slow_path->GetEntryLabel()); diff --git a/compiler/optimizing/code_generator_arm_vixl.cc b/compiler/optimizing/code_generator_arm_vixl.cc index 1f814abf06..3df55ae851 100644 --- a/compiler/optimizing/code_generator_arm_vixl.cc +++ b/compiler/optimizing/code_generator_arm_vixl.cc @@ -5200,11 +5200,14 @@ void InstructionCodeGeneratorARMVIXL::VisitInstanceOf(HInstanceOf* instruction) __ Cbz(obj, &zero); } - // /* HeapReference<Class> */ out = obj->klass_ - GenerateReferenceLoadTwoRegisters(instruction, out_loc, obj_loc, class_offset, maybe_temp_loc); - switch (type_check_kind) { case TypeCheckKind::kExactCheck: { + // /* HeapReference<Class> */ out = obj->klass_ + GenerateReferenceLoadTwoRegisters(instruction, + out_loc, + obj_loc, + class_offset, + maybe_temp_loc); __ Cmp(out, cls); // Classes must be equal for the instanceof to succeed. __ B(ne, &zero); @@ -5214,6 +5217,12 @@ void InstructionCodeGeneratorARMVIXL::VisitInstanceOf(HInstanceOf* instruction) } case TypeCheckKind::kAbstractClassCheck: { + // /* HeapReference<Class> */ out = obj->klass_ + GenerateReferenceLoadTwoRegisters(instruction, + out_loc, + obj_loc, + class_offset, + maybe_temp_loc); // If the class is abstract, we eagerly fetch the super class of the // object to avoid doing a comparison we know will fail. vixl32::Label loop; @@ -5232,6 +5241,12 @@ void InstructionCodeGeneratorARMVIXL::VisitInstanceOf(HInstanceOf* instruction) } case TypeCheckKind::kClassHierarchyCheck: { + // /* HeapReference<Class> */ out = obj->klass_ + GenerateReferenceLoadTwoRegisters(instruction, + out_loc, + obj_loc, + class_offset, + maybe_temp_loc); // Walk over the class hierarchy to find a match. vixl32::Label loop, success; __ Bind(&loop); @@ -5251,6 +5266,12 @@ void InstructionCodeGeneratorARMVIXL::VisitInstanceOf(HInstanceOf* instruction) } case TypeCheckKind::kArrayObjectCheck: { + // /* HeapReference<Class> */ out = obj->klass_ + GenerateReferenceLoadTwoRegisters(instruction, + out_loc, + obj_loc, + class_offset, + maybe_temp_loc); // Do an exact check. vixl32::Label exact_check; __ Cmp(out, cls); @@ -5270,6 +5291,12 @@ void InstructionCodeGeneratorARMVIXL::VisitInstanceOf(HInstanceOf* instruction) } case TypeCheckKind::kArrayCheck: { + // /* HeapReference<Class> */ out = obj->klass_ + GenerateReferenceLoadTwoRegisters(instruction, + out_loc, + obj_loc, + class_offset, + maybe_temp_loc); __ Cmp(out, cls); DCHECK(locations->OnlyCallsOnSlowPath()); slow_path = new (GetGraph()->GetArena()) TypeCheckSlowPathARMVIXL(instruction, diff --git a/compiler/optimizing/code_generator_x86.cc b/compiler/optimizing/code_generator_x86.cc index 2451b8d247..7e4ad267c8 100644 --- a/compiler/optimizing/code_generator_x86.cc +++ b/compiler/optimizing/code_generator_x86.cc @@ -6849,24 +6849,24 @@ void InstructionCodeGeneratorX86::VisitCheckCast(HCheckCast* instruction) { temp_loc, iftable_offset, kWithoutReadBarrier); - // Null iftable means it is empty. - __ testl(temp, temp); - __ j(kZero, type_check_slow_path->GetEntryLabel()); - - // Loop through the iftable and check if any class matches. + // Iftable is never null. __ movl(maybe_temp2_loc.AsRegister<Register>(), Address(temp, array_length_offset)); - + // Loop through the iftable and check if any class matches. NearLabel start_loop; __ Bind(&start_loop); - __ cmpl(cls.AsRegister<Register>(), Address(temp, object_array_data_offset)); - __ j(kEqual, &done); // Return if same class. - // Go to next interface. - __ addl(temp, Immediate(2 * kHeapReferenceSize)); + // Need to subtract first to handle the empty array case. __ subl(maybe_temp2_loc.AsRegister<Register>(), Immediate(2)); - __ j(kNotZero, &start_loop); + __ j(kNegative, type_check_slow_path->GetEntryLabel()); + // Go to next interface if the classes do not match. + __ cmpl(cls.AsRegister<Register>(), + CodeGeneratorX86::ArrayAddress(temp, + maybe_temp2_loc, + TIMES_4, + object_array_data_offset)); + __ j(kNotEqual, &start_loop); + } else { + __ jmp(type_check_slow_path->GetEntryLabel()); } - - __ jmp(type_check_slow_path->GetEntryLabel()); break; } } @@ -7562,7 +7562,7 @@ class RIPFixup : public AssemblerFixup, public ArenaObject<kArenaAllocCodeGenera // The value to patch is the distance from the offset in the constant area // from the address computed by the HX86ComputeBaseMethodAddress instruction. int32_t constant_offset = codegen_->ConstantAreaStart() + offset_into_constant_area_; - int32_t relative_position = constant_offset - codegen_->GetMethodAddressOffset();; + int32_t relative_position = constant_offset - codegen_->GetMethodAddressOffset(); // Patch in the right value. region.StoreUnaligned<int32_t>(pos - 4, relative_position); diff --git a/compiler/optimizing/code_generator_x86_64.cc b/compiler/optimizing/code_generator_x86_64.cc index 2425a4c3cb..19b30192cd 100644 --- a/compiler/optimizing/code_generator_x86_64.cc +++ b/compiler/optimizing/code_generator_x86_64.cc @@ -6259,23 +6259,24 @@ void InstructionCodeGeneratorX86_64::VisitCheckCast(HCheckCast* instruction) { temp_loc, iftable_offset, kWithoutReadBarrier); - // Null iftable means it is empty. - __ testl(temp, temp); - __ j(kZero, type_check_slow_path->GetEntryLabel()); - - // Loop through the iftable and check if any class matches. + // Iftable is never null. __ movl(maybe_temp2_loc.AsRegister<CpuRegister>(), Address(temp, array_length_offset)); - + // Loop through the iftable and check if any class matches. NearLabel start_loop; __ Bind(&start_loop); - __ cmpl(cls.AsRegister<CpuRegister>(), Address(temp, object_array_data_offset)); - __ j(kEqual, &done); // Return if same class. - // Go to next interface. - __ addl(temp, Immediate(2 * kHeapReferenceSize)); + // Need to subtract first to handle the empty array case. __ subl(maybe_temp2_loc.AsRegister<CpuRegister>(), Immediate(2)); - __ j(kNotZero, &start_loop); + __ j(kNegative, type_check_slow_path->GetEntryLabel()); + // Go to next interface if the classes do not match. + __ cmpl(cls.AsRegister<CpuRegister>(), + CodeGeneratorX86_64::ArrayAddress(temp, + maybe_temp2_loc, + TIMES_4, + object_array_data_offset)); + __ j(kNotEqual, &start_loop); // Return if same class. + } else { + __ jmp(type_check_slow_path->GetEntryLabel()); } - __ jmp(type_check_slow_path->GetEntryLabel()); break; } |