Add support for unresolved classes in optimizing.
Change-Id: I0e299a81e560eb9cb0737ec46125dffc99333b54
diff --git a/compiler/optimizing/code_generator_arm.cc b/compiler/optimizing/code_generator_arm.cc
index 299350b..54af41d 100644
--- a/compiler/optimizing/code_generator_arm.cc
+++ b/compiler/optimizing/code_generator_arm.cc
@@ -4468,20 +4468,24 @@
}
void LocationsBuilderARM::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(R0));
}
void InstructionCodeGeneratorARM::VisitLoadClass(HLoadClass* cls) {
LocationSummary* locations = cls->GetLocations();
Register out = locations->Out().AsRegister<Register>();
Register current_method = locations->InAt(0).AsRegister<Register>();
- 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());
__ LoadFromOffset(
@@ -4604,6 +4608,7 @@
case TypeCheckKind::kArrayObjectCheck:
call_kind = LocationSummary::kNoCall;
break;
+ case TypeCheckKind::kUnresolvedCheck:
case TypeCheckKind::kInterfaceCheck:
call_kind = LocationSummary::kCall;
break;
@@ -4644,10 +4649,11 @@
__ CompareAndBranchIfZero(obj, &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.
- Register target = (instruction->GetTypeCheckKind() == TypeCheckKind::kInterfaceCheck)
+ Register target = (instruction->GetTypeCheckKind() == TypeCheckKind::kInterfaceCheck) ||
+ (instruction->GetTypeCheckKind() == TypeCheckKind::kUnresolvedCheck)
? obj
: out;
__ LoadFromOffset(kLoadWord, target, obj, class_offset);
@@ -4728,7 +4734,7 @@
}
break;
}
-
+ case TypeCheckKind::kUnresolvedCheck:
case TypeCheckKind::kInterfaceCheck:
default: {
codegen_->InvokeRuntime(QUICK_ENTRY_POINT(pInstanceofNonTrivial),
@@ -4769,6 +4775,7 @@
? LocationSummary::kCallOnSlowPath
: LocationSummary::kNoCall;
break;
+ case TypeCheckKind::kUnresolvedCheck:
case TypeCheckKind::kInterfaceCheck:
call_kind = LocationSummary::kCall;
break;
@@ -4873,6 +4880,7 @@
__ CompareAndBranchIfNonZero(temp, slow_path->GetEntryLabel());
break;
}
+ case TypeCheckKind::kUnresolvedCheck:
case TypeCheckKind::kInterfaceCheck:
default:
codegen_->InvokeRuntime(QUICK_ENTRY_POINT(pCheckCast),