From 38f64d325867d3e7197da6e07b1d4d9ba8497427 Mon Sep 17 00:00:00 2001 From: David Brazdil Date: Mon, 18 Jan 2016 17:13:41 +0000 Subject: 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 --- compiler/driver/compiler_driver.cc | 43 ++++++++++++++++++++++---------------- 1 file changed, 25 insertions(+), 18 deletions(-) (limited to 'compiler/driver/compiler_driver.cc') 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 { -- cgit v1.2.3-59-g8ed1b