Add support for unresolved classes in optimizing.
Change-Id: I0e299a81e560eb9cb0737ec46125dffc99333b54
diff --git a/compiler/optimizing/code_generator_x86_64.cc b/compiler/optimizing/code_generator_x86_64.cc
index 791bb9e..ad6588c 100644
--- a/compiler/optimizing/code_generator_x86_64.cc
+++ b/compiler/optimizing/code_generator_x86_64.cc
@@ -4694,20 +4694,24 @@
}
void LocationsBuilderX86_64::VisitLoadClass(HLoadClass* cls) {
- LocationSummary::CallKind call_kind = cls->CanCallRuntime()
- ? LocationSummary::kCallOnSlowPath
- : LocationSummary::kNoCall;
- LocationSummary* locations =
- new (GetGraph()->GetArena()) LocationSummary(cls, call_kind);
- locations->SetInAt(0, Location::RequiresRegister());
- locations->SetOut(Location::RequiresRegister());
+ InvokeRuntimeCallingConvention calling_convention;
+ CodeGenerator::CreateLoadClassLocationSummary(
+ cls,
+ Location::RegisterLocation(calling_convention.GetRegisterAt(0)),
+ Location::RegisterLocation(RAX));
}
void InstructionCodeGeneratorX86_64::VisitLoadClass(HLoadClass* cls) {
LocationSummary* locations = cls->GetLocations();
CpuRegister out = locations->Out().AsRegister<CpuRegister>();
CpuRegister current_method = locations->InAt(0).AsRegister<CpuRegister>();
- if (cls->IsReferrersClass()) {
+ if (cls->NeedsAccessCheck()) {
+ codegen_->MoveConstant(locations->GetTemp(0), cls->GetTypeIndex());
+ codegen_->InvokeRuntime(QUICK_ENTRY_POINT(pInitializeTypeAndVerifyAccess),
+ cls,
+ cls->GetDexPc(),
+ nullptr);
+ } else if (cls->IsReferrersClass()) {
DCHECK(!cls->CanCallRuntime());
DCHECK(!cls->MustGenerateClinitCheck());
__ movl(out, Address(current_method, ArtMethod::DeclaringClassOffset().Int32Value()));
@@ -4817,6 +4821,7 @@
case TypeCheckKind::kArrayObjectCheck:
call_kind = LocationSummary::kNoCall;
break;
+ case TypeCheckKind::kUnresolvedCheck:
case TypeCheckKind::kInterfaceCheck:
call_kind = LocationSummary::kCall;
break;
@@ -4857,10 +4862,11 @@
__ j(kEqual, &zero);
}
- // In case of an interface check, we put the object class into the object register.
+ // In case of an interface/unresolved check, we put the object class into the object register.
// This is safe, as the register is caller-save, and the object must be in another
// register if it survives the runtime call.
- CpuRegister target = (instruction->GetTypeCheckKind() == TypeCheckKind::kInterfaceCheck)
+ CpuRegister target = (instruction->GetTypeCheckKind() == TypeCheckKind::kInterfaceCheck) ||
+ (instruction->GetTypeCheckKind() == TypeCheckKind::kUnresolvedCheck)
? obj
: out;
__ movl(target, Address(obj, class_offset));
@@ -4974,7 +4980,7 @@
}
break;
}
-
+ case TypeCheckKind::kUnresolvedCheck:
case TypeCheckKind::kInterfaceCheck:
default: {
codegen_->InvokeRuntime(QUICK_ENTRY_POINT(pInstanceofNonTrivial),
@@ -5015,6 +5021,7 @@
? LocationSummary::kCallOnSlowPath
: LocationSummary::kNoCall;
break;
+ case TypeCheckKind::kUnresolvedCheck:
case TypeCheckKind::kInterfaceCheck:
call_kind = LocationSummary::kCall;
break;
@@ -5142,6 +5149,7 @@
__ j(kNotEqual, slow_path->GetEntryLabel());
break;
}
+ case TypeCheckKind::kUnresolvedCheck:
case TypeCheckKind::kInterfaceCheck:
default:
codegen_->InvokeRuntime(QUICK_ENTRY_POINT(pCheckCast),