diff options
Diffstat (limited to 'compiler/optimizing/sharpening.cc')
| -rw-r--r-- | compiler/optimizing/sharpening.cc | 69 | 
1 files changed, 69 insertions, 0 deletions
diff --git a/compiler/optimizing/sharpening.cc b/compiler/optimizing/sharpening.cc index 7dffb2a378..70b45763af 100644 --- a/compiler/optimizing/sharpening.cc +++ b/compiler/optimizing/sharpening.cc @@ -240,6 +240,75 @@ HLoadClass::LoadKind HSharpening::ComputeLoadClassKind(    return load_kind;  } +static inline bool CanUseTypeCheckBitstring(ObjPtr<mirror::Class> klass, +                                            CodeGenerator* codegen, +                                            CompilerDriver* compiler_driver) +    REQUIRES_SHARED(Locks::mutator_lock_) { +  DCHECK(!klass->IsProxyClass()); +  DCHECK(!klass->IsArrayClass()); + +  if (Runtime::Current()->UseJitCompilation()) { +    // If we're JITting, try to assign a type check bitstring (fall through). +  } else if (codegen->GetCompilerOptions().IsBootImage()) { +    const char* descriptor = klass->GetDexFile().StringByTypeIdx(klass->GetDexTypeIndex()); +    if (!compiler_driver->IsImageClass(descriptor)) { +      return false; +    } +    // If the target is a boot image class, try to assign a type check bitstring (fall through). +    // (If --force-determinism, this was already done; repeating is OK and yields the same result.) +  } else { +    // TODO: Use the bitstring also for AOT app compilation if the target class has a bitstring +    // already assigned in the boot image. +    return false; +  } + +  // Try to assign a type check bitstring. +  MutexLock subtype_check_lock(Thread::Current(), *Locks::subtype_check_lock_); +  if ((false) &&  // FIXME: Inliner does not respect compiler_driver->IsClassToCompile() +                  // and we're hitting an unassigned bitstring in dex2oat_image_test. b/26687569 +      kIsDebugBuild && +      codegen->GetCompilerOptions().IsBootImage() && +      codegen->GetCompilerOptions().IsForceDeterminism()) { +    SubtypeCheckInfo::State old_state = SubtypeCheck<ObjPtr<mirror::Class>>::GetState(klass); +    CHECK(old_state == SubtypeCheckInfo::kAssigned || old_state == SubtypeCheckInfo::kOverflowed) +        << klass->PrettyDescriptor() << "/" << old_state +        << " in " << codegen->GetGraph()->PrettyMethod(); +  } +  SubtypeCheckInfo::State state = SubtypeCheck<ObjPtr<mirror::Class>>::EnsureAssigned(klass); +  return state == SubtypeCheckInfo::kAssigned; +} + +TypeCheckKind HSharpening::ComputeTypeCheckKind(ObjPtr<mirror::Class> klass, +                                                CodeGenerator* codegen, +                                                CompilerDriver* compiler_driver, +                                                bool needs_access_check) { +  if (klass == nullptr) { +    return TypeCheckKind::kUnresolvedCheck; +  } else if (klass->IsInterface()) { +    return TypeCheckKind::kInterfaceCheck; +  } else if (klass->IsArrayClass()) { +    if (klass->GetComponentType()->IsObjectClass()) { +      return TypeCheckKind::kArrayObjectCheck; +    } else if (klass->CannotBeAssignedFromOtherTypes()) { +      return TypeCheckKind::kExactCheck; +    } else { +      return TypeCheckKind::kArrayCheck; +    } +  } else if (klass->IsFinal()) {  // TODO: Consider using bitstring for final classes. +    return TypeCheckKind::kExactCheck; +  } else if (kBitstringSubtypeCheckEnabled && +             !needs_access_check && +             CanUseTypeCheckBitstring(klass, codegen, compiler_driver)) { +    // TODO: We should not need the `!needs_access_check` check but getting rid of that +    // requires rewriting some optimizations in instruction simplifier. +    return TypeCheckKind::kBitstringCheck; +  } else if (klass->IsAbstract()) { +    return TypeCheckKind::kAbstractClassCheck; +  } else { +    return TypeCheckKind::kClassHierarchyCheck; +  } +} +  void HSharpening::ProcessLoadString(      HLoadString* load_string,      CodeGenerator* codegen,  |