diff options
author | 2016-01-18 17:13:41 +0000 | |
---|---|---|
committer | 2016-01-18 18:40:10 +0000 | |
commit | 38f64d325867d3e7197da6e07b1d4d9ba8497427 (patch) | |
tree | 6aa220b7f86da5a68d1a666362dfbacee199cc68 /compiler/driver/compiler_driver.cc | |
parent | b8bb9f6d0b59be125066f604f134155f8998f5ae (diff) |
ART: Public classes never require access checks
CompilerDriver's CanAccess(Instantiable)TypeWithoutChecks will always
return false if the referrer class is unresolved. This is too
conservative when the target class is resolved and known public.
Change-Id: Ibf95f43f13a7295e85671e3b71e28b5d88b4ca3b
Diffstat (limited to 'compiler/driver/compiler_driver.cc')
-rw-r--r-- | compiler/driver/compiler_driver.cc | 43 |
1 files changed, 25 insertions, 18 deletions
diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc index 043bd93bd7..56e5abe194 100644 --- a/compiler/driver/compiler_driver.cc +++ b/compiler/driver/compiler_driver.cc @@ -1197,15 +1197,18 @@ bool CompilerDriver::CanAccessTypeWithoutChecks(uint32_t referrer_idx, const Dex if (equals_referrers_class != nullptr) { *equals_referrers_class = (method_id.class_idx_ == type_idx); } - mirror::Class* referrer_class = dex_cache->GetResolvedType(method_id.class_idx_); - if (referrer_class == nullptr) { - stats_->TypeNeedsAccessCheck(); - return false; // Incomplete referrer knowledge needs access check. - } - // Perform access check, will return true if access is ok or false if we're going to have to - // check this at runtime (for example for class loaders). - bool result = referrer_class->CanAccess(resolved_class); - if (result) { + bool is_accessible = resolved_class->IsPublic(); // Public classes are always accessible. + if (!is_accessible) { + mirror::Class* referrer_class = dex_cache->GetResolvedType(method_id.class_idx_); + if (referrer_class == nullptr) { + stats_->TypeNeedsAccessCheck(); + return false; // Incomplete referrer knowledge needs access check. + } + // Perform access check, will return true if access is ok or false if we're going to have to + // check this at runtime (for example for class loaders). + is_accessible = referrer_class->CanAccess(resolved_class); + } + if (is_accessible) { stats_->TypeDoesntNeedAccessCheck(); if (type_known_final != nullptr) { *type_known_final = resolved_class->IsFinal() && !resolved_class->IsArrayClass(); @@ -1216,7 +1219,7 @@ bool CompilerDriver::CanAccessTypeWithoutChecks(uint32_t referrer_idx, const Dex } else { stats_->TypeNeedsAccessCheck(); } - return result; + return is_accessible; } bool CompilerDriver::CanAccessInstantiableTypeWithoutChecks(uint32_t referrer_idx, @@ -1236,14 +1239,18 @@ bool CompilerDriver::CanAccessInstantiableTypeWithoutChecks(uint32_t referrer_id } *finalizable = resolved_class->IsFinalizable(); const DexFile::MethodId& method_id = dex_file.GetMethodId(referrer_idx); - mirror::Class* referrer_class = dex_cache->GetResolvedType(method_id.class_idx_); - if (referrer_class == nullptr) { - stats_->TypeNeedsAccessCheck(); - return false; // Incomplete referrer knowledge needs access check. - } - // Perform access and instantiable checks, will return true if access is ok or false if we're - // going to have to check this at runtime (for example for class loaders). - bool result = referrer_class->CanAccess(resolved_class) && resolved_class->IsInstantiable(); + bool is_accessible = resolved_class->IsPublic(); // Public classes are always accessible. + if (!is_accessible) { + mirror::Class* referrer_class = dex_cache->GetResolvedType(method_id.class_idx_); + if (referrer_class == nullptr) { + stats_->TypeNeedsAccessCheck(); + return false; // Incomplete referrer knowledge needs access check. + } + // Perform access and instantiable checks, will return true if access is ok or false if we're + // going to have to check this at runtime (for example for class loaders). + is_accessible = referrer_class->CanAccess(resolved_class); + } + bool result = is_accessible && resolved_class->IsInstantiable(); if (result) { stats_->TypeDoesntNeedAccessCheck(); } else { |