Revert^3 "Hash-based dex cache type array."
Assert failing for "earchbox:search":
F zygote64: class_linker.cc:4612] Check failed: handle_scope_iface.Get() != nullptr
Test: m test-art-host
Bug: 34839984
Bug: 30627598
Bug: 34659969
This reverts commit 85c0f2ac03417f5125bc2ff1dab8109859c67d5c.
Change-Id: I39846c20295af5875b0f945be7035c73ded23135
diff --git a/compiler/driver/compiler_driver-inl.h b/compiler/driver/compiler_driver-inl.h
index 5823306..f296851 100644
--- a/compiler/driver/compiler_driver-inl.h
+++ b/compiler/driver/compiler_driver-inl.h
@@ -31,12 +31,17 @@
namespace art {
+inline mirror::ClassLoader* CompilerDriver::GetClassLoader(const ScopedObjectAccess& soa,
+ const DexCompilationUnit* mUnit) {
+ return soa.Decode<mirror::ClassLoader>(mUnit->GetClassLoader()).Ptr();
+}
+
inline mirror::Class* CompilerDriver::ResolveClass(
const ScopedObjectAccess& soa, Handle<mirror::DexCache> dex_cache,
Handle<mirror::ClassLoader> class_loader, dex::TypeIndex cls_index,
const DexCompilationUnit* mUnit) {
DCHECK_EQ(dex_cache->GetDexFile(), mUnit->GetDexFile());
- DCHECK_EQ(class_loader.Get(), mUnit->GetClassLoader().Get());
+ DCHECK_EQ(class_loader.Get(), GetClassLoader(soa, mUnit));
mirror::Class* cls = mUnit->GetClassLinker()->ResolveType(
*mUnit->GetDexFile(), cls_index, dex_cache, class_loader);
DCHECK_EQ(cls == nullptr, soa.Self()->IsExceptionPending());
@@ -51,7 +56,7 @@
const ScopedObjectAccess& soa, Handle<mirror::DexCache> dex_cache,
Handle<mirror::ClassLoader> class_loader, const DexCompilationUnit* mUnit) {
DCHECK_EQ(dex_cache->GetDexFile(), mUnit->GetDexFile());
- DCHECK_EQ(class_loader.Get(), mUnit->GetClassLoader().Get());
+ DCHECK_EQ(class_loader.Get(), GetClassLoader(soa, mUnit));
const DexFile::MethodId& referrer_method_id =
mUnit->GetDexFile()->GetMethodId(mUnit->GetDexMethodIndex());
return ResolveClass(soa, dex_cache, class_loader, referrer_method_id.class_idx_, mUnit);
@@ -82,7 +87,7 @@
const ScopedObjectAccess& soa, Handle<mirror::DexCache> dex_cache,
Handle<mirror::ClassLoader> class_loader, const DexCompilationUnit* mUnit,
uint32_t field_idx, bool is_static) {
- DCHECK_EQ(class_loader.Get(), mUnit->GetClassLoader().Get());
+ DCHECK_EQ(class_loader.Get(), GetClassLoader(soa, mUnit));
return ResolveFieldWithDexFile(soa, dex_cache, class_loader, mUnit->GetDexFile(), field_idx,
is_static);
}
@@ -134,7 +139,7 @@
ScopedObjectAccess& soa, Handle<mirror::DexCache> dex_cache,
Handle<mirror::ClassLoader> class_loader, const DexCompilationUnit* mUnit,
uint32_t method_idx, InvokeType invoke_type, bool check_incompatible_class_change) {
- DCHECK_EQ(class_loader.Get(), mUnit->GetClassLoader().Get());
+ DCHECK_EQ(class_loader.Get(), GetClassLoader(soa, mUnit));
ArtMethod* resolved_method =
check_incompatible_class_change
? mUnit->GetClassLinker()->ResolveMethod<ClassLinker::kForceICCECheck>(
diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc
index b738d5c..7af850a 100644
--- a/compiler/driver/compiler_driver.cc
+++ b/compiler/driver/compiler_driver.cc
@@ -583,7 +583,7 @@
InvokeType invoke_type,
uint16_t class_def_idx,
uint32_t method_idx,
- Handle<mirror::ClassLoader> class_loader,
+ jobject class_loader,
const DexFile& dex_file,
optimizer::DexToDexCompilationLevel dex_to_dex_compilation_level,
bool compilation_enabled,
@@ -624,6 +624,9 @@
// Look-up the ArtMethod associated with this code_item (if any)
// -- It is later used to lookup any [optimization] annotations for this method.
ScopedObjectAccess soa(self);
+ StackHandleScope<1> hs(soa.Self());
+ Handle<mirror::ClassLoader> class_loader_handle(hs.NewHandle(
+ soa.Decode<mirror::ClassLoader>(class_loader)));
// TODO: Lookup annotation from DexFile directly without resolving method.
ArtMethod* method =
@@ -631,7 +634,7 @@
dex_file,
method_idx,
dex_cache,
- class_loader,
+ class_loader_handle,
/* referrer */ nullptr,
invoke_type);
@@ -678,14 +681,9 @@
if (compile) {
// NOTE: if compiler declines to compile this method, it will return null.
- compiled_method = driver->GetCompiler()->Compile(code_item,
- access_flags,
- invoke_type,
- class_def_idx,
- method_idx,
- class_loader,
- dex_file,
- dex_cache);
+ compiled_method = driver->GetCompiler()->Compile(code_item, access_flags, invoke_type,
+ class_def_idx, method_idx, class_loader,
+ dex_file, dex_cache);
}
if (compiled_method == nullptr &&
dex_to_dex_compilation_level != optimizer::DexToDexCompilationLevel::kDontDexToDexCompile) {
@@ -732,14 +730,12 @@
uint32_t method_idx = method->GetDexMethodIndex();
uint32_t access_flags = method->GetAccessFlags();
InvokeType invoke_type = method->GetInvokeType();
- StackHandleScope<2> hs(self);
+ StackHandleScope<1> hs(self);
Handle<mirror::DexCache> dex_cache(hs.NewHandle(method->GetDexCache()));
- Handle<mirror::ClassLoader> class_loader(
- hs.NewHandle(method->GetDeclaringClass()->GetClassLoader()));
{
ScopedObjectAccessUnchecked soa(self);
ScopedLocalRef<jobject> local_class_loader(
- soa.Env(), soa.AddLocalReference<jobject>(class_loader.Get()));
+ soa.Env(), soa.AddLocalReference<jobject>(method->GetDeclaringClass()->GetClassLoader()));
jclass_loader = soa.Env()->NewGlobalRef(local_class_loader.get());
// Find the dex_file
dex_file = method->GetDexFile();
@@ -773,7 +769,7 @@
invoke_type,
class_def_idx,
method_idx,
- class_loader,
+ jclass_loader,
*dex_file,
dex_to_dex_compilation_level,
true,
@@ -799,7 +795,7 @@
invoke_type,
class_def_idx,
method_idx,
- class_loader,
+ jclass_loader,
*dex_file,
dex_to_dex_compilation_level,
true,
@@ -1074,30 +1070,22 @@
class ResolveCatchBlockExceptionsClassVisitor : public ClassVisitor {
public:
- ResolveCatchBlockExceptionsClassVisitor() : classes_() {}
+ explicit ResolveCatchBlockExceptionsClassVisitor(
+ std::set<std::pair<dex::TypeIndex, const DexFile*>>& exceptions_to_resolve)
+ : exceptions_to_resolve_(exceptions_to_resolve) {}
virtual bool operator()(ObjPtr<mirror::Class> c) OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_) {
- classes_.push_back(c);
+ const auto pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
+ for (auto& m : c->GetMethods(pointer_size)) {
+ ResolveExceptionsForMethod(&m);
+ }
return true;
}
- void FindExceptionTypesToResolve(
- std::set<std::pair<dex::TypeIndex, const DexFile*>>* exceptions_to_resolve)
- REQUIRES_SHARED(Locks::mutator_lock_) {
- const auto pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
- for (ObjPtr<mirror::Class> klass : classes_) {
- for (ArtMethod& method : klass->GetMethods(pointer_size)) {
- FindExceptionTypesToResolveForMethod(&method, exceptions_to_resolve);
- }
- }
- }
-
private:
- void FindExceptionTypesToResolveForMethod(
- ArtMethod* method,
- std::set<std::pair<dex::TypeIndex, const DexFile*>>* exceptions_to_resolve)
+ void ResolveExceptionsForMethod(ArtMethod* method_handle)
REQUIRES_SHARED(Locks::mutator_lock_) {
- const DexFile::CodeItem* code_item = method->GetCodeItem();
+ const DexFile::CodeItem* code_item = method_handle->GetCodeItem();
if (code_item == nullptr) {
return; // native or abstract method
}
@@ -1117,9 +1105,9 @@
dex::TypeIndex encoded_catch_handler_handlers_type_idx =
dex::TypeIndex(DecodeUnsignedLeb128(&encoded_catch_handler_list));
// Add to set of types to resolve if not already in the dex cache resolved types
- if (!method->IsResolvedTypeIdx(encoded_catch_handler_handlers_type_idx)) {
- exceptions_to_resolve->emplace(encoded_catch_handler_handlers_type_idx,
- method->GetDexFile());
+ if (!method_handle->IsResolvedTypeIdx(encoded_catch_handler_handlers_type_idx)) {
+ exceptions_to_resolve_.emplace(encoded_catch_handler_handlers_type_idx,
+ method_handle->GetDexFile());
}
// ignore address associated with catch handler
DecodeUnsignedLeb128(&encoded_catch_handler_list);
@@ -1131,7 +1119,7 @@
}
}
- std::vector<ObjPtr<mirror::Class>> classes_;
+ std::set<std::pair<dex::TypeIndex, const DexFile*>>& exceptions_to_resolve_;
};
class RecordImageClassesVisitor : public ClassVisitor {
@@ -1185,14 +1173,8 @@
hs.NewHandle(class_linker->FindSystemClass(self, "Ljava/lang/Throwable;")));
do {
unresolved_exception_types.clear();
- {
- // Thread suspension is not allowed while ResolveCatchBlockExceptionsClassVisitor
- // is using a std::vector<ObjPtr<mirror::Class>>.
- ScopedAssertNoThreadSuspension ants(__FUNCTION__);
- ResolveCatchBlockExceptionsClassVisitor visitor;
- class_linker->VisitClasses(&visitor);
- visitor.FindExceptionTypesToResolve(&unresolved_exception_types);
- }
+ ResolveCatchBlockExceptionsClassVisitor visitor(unresolved_exception_types);
+ class_linker->VisitClasses(&visitor);
for (const auto& exception_type : unresolved_exception_types) {
dex::TypeIndex exception_type_idx = exception_type.first;
const DexFile* dex_file = exception_type.second;
@@ -1443,14 +1425,19 @@
dex_to_dex_references_.back().GetMethodIndexes().SetBit(method_ref.dex_method_index);
}
-bool CompilerDriver::CanAccessTypeWithoutChecks(ObjPtr<mirror::Class> referrer_class,
- ObjPtr<mirror::Class> resolved_class) {
+bool CompilerDriver::CanAccessTypeWithoutChecks(uint32_t referrer_idx,
+ Handle<mirror::DexCache> dex_cache,
+ dex::TypeIndex type_idx) {
+ // Get type from dex cache assuming it was populated by the verifier
+ mirror::Class* resolved_class = dex_cache->GetResolvedType(type_idx);
if (resolved_class == nullptr) {
stats_->TypeNeedsAccessCheck();
return false; // Unknown class needs access checks.
}
+ const DexFile::MethodId& method_id = dex_cache->GetDexFile()->GetMethodId(referrer_idx);
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.
@@ -1467,9 +1454,12 @@
return is_accessible;
}
-bool CompilerDriver::CanAccessInstantiableTypeWithoutChecks(ObjPtr<mirror::Class> referrer_class,
- ObjPtr<mirror::Class> resolved_class,
+bool CompilerDriver::CanAccessInstantiableTypeWithoutChecks(uint32_t referrer_idx,
+ Handle<mirror::DexCache> dex_cache,
+ dex::TypeIndex type_idx,
bool* finalizable) {
+ // Get type from dex cache assuming it was populated by the verifier.
+ mirror::Class* resolved_class = dex_cache->GetResolvedType(type_idx);
if (resolved_class == nullptr) {
stats_->TypeNeedsAccessCheck();
// Be conservative.
@@ -1477,8 +1467,10 @@
return false; // Unknown class needs access checks.
}
*finalizable = resolved_class->IsFinalizable();
+ const DexFile::MethodId& method_id = dex_cache->GetDexFile()->GetMethodId(referrer_idx);
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.
@@ -1522,7 +1514,9 @@
mirror::Class* referrer_class;
Handle<mirror::DexCache> dex_cache(mUnit->GetDexCache());
{
- Handle<mirror::ClassLoader> class_loader_handle = mUnit->GetClassLoader();
+ StackHandleScope<1> hs(soa.Self());
+ Handle<mirror::ClassLoader> class_loader_handle(
+ hs.NewHandle(soa.Decode<mirror::ClassLoader>(mUnit->GetClassLoader())));
resolved_field = ResolveField(soa, dex_cache, class_loader_handle, mUnit, field_idx, false);
referrer_class = resolved_field != nullptr
? ResolveCompilingMethodsClass(soa, dex_cache, class_loader_handle, mUnit) : nullptr;
@@ -2594,18 +2588,10 @@
continue;
}
previous_direct_method_idx = method_idx;
- CompileMethod(soa.Self(),
- driver,
- it.GetMethodCodeItem(),
- it.GetMethodAccessFlags(),
- it.GetMethodInvokeType(class_def),
- class_def_index,
- method_idx,
- class_loader,
- dex_file,
- dex_to_dex_compilation_level,
- compilation_enabled,
- dex_cache);
+ CompileMethod(soa.Self(), driver, it.GetMethodCodeItem(), it.GetMethodAccessFlags(),
+ it.GetMethodInvokeType(class_def), class_def_index,
+ method_idx, jclass_loader, dex_file, dex_to_dex_compilation_level,
+ compilation_enabled, dex_cache);
it.Next();
}
// Compile virtual methods
@@ -2619,17 +2605,10 @@
continue;
}
previous_virtual_method_idx = method_idx;
- CompileMethod(soa.Self(),
- driver, it.GetMethodCodeItem(),
- it.GetMethodAccessFlags(),
- it.GetMethodInvokeType(class_def),
- class_def_index,
- method_idx,
- class_loader,
- dex_file,
- dex_to_dex_compilation_level,
- compilation_enabled,
- dex_cache);
+ CompileMethod(soa.Self(), driver, it.GetMethodCodeItem(), it.GetMethodAccessFlags(),
+ it.GetMethodInvokeType(class_def), class_def_index,
+ method_idx, jclass_loader, dex_file, dex_to_dex_compilation_level,
+ compilation_enabled, dex_cache);
it.Next();
}
DCHECK(!it.HasNext());
diff --git a/compiler/driver/compiler_driver.h b/compiler/driver/compiler_driver.h
index 1e5c43d..5b4c751 100644
--- a/compiler/driver/compiler_driver.h
+++ b/compiler/driver/compiler_driver.h
@@ -187,14 +187,16 @@
REQUIRES(!requires_constructor_barrier_lock_);
// Are runtime access checks necessary in the compiled code?
- bool CanAccessTypeWithoutChecks(ObjPtr<mirror::Class> referrer_class,
- ObjPtr<mirror::Class> resolved_class)
+ bool CanAccessTypeWithoutChecks(uint32_t referrer_idx,
+ Handle<mirror::DexCache> dex_cache,
+ dex::TypeIndex type_idx)
REQUIRES_SHARED(Locks::mutator_lock_);
// Are runtime access and instantiable checks necessary in the code?
// out_is_finalizable is set to whether the type is finalizable.
- bool CanAccessInstantiableTypeWithoutChecks(ObjPtr<mirror::Class> referrer_class,
- ObjPtr<mirror::Class> resolved_class,
+ bool CanAccessInstantiableTypeWithoutChecks(uint32_t referrer_idx,
+ Handle<mirror::DexCache> dex_cache,
+ dex::TypeIndex type_idx,
bool* out_is_finalizable)
REQUIRES_SHARED(Locks::mutator_lock_);
@@ -368,6 +370,10 @@
uint32_t field_idx)
REQUIRES_SHARED(Locks::mutator_lock_);
+ mirror::ClassLoader* GetClassLoader(const ScopedObjectAccess& soa,
+ const DexCompilationUnit* mUnit)
+ REQUIRES_SHARED(Locks::mutator_lock_);
+
private:
void PreCompile(jobject class_loader,
const std::vector<const DexFile*>& dex_files,
diff --git a/compiler/driver/compiler_driver_test.cc b/compiler/driver/compiler_driver_test.cc
index e4b66eb..1e4ca16 100644
--- a/compiler/driver/compiler_driver_test.cc
+++ b/compiler/driver/compiler_driver_test.cc
@@ -101,7 +101,6 @@
};
// Disabled due to 10 second runtime on host
-// TODO: Update the test for hash-based dex cache arrays. Bug: 30627598
TEST_F(CompilerDriverTest, DISABLED_LARGE_CompileDexLibCore) {
CompileAll(nullptr);
diff --git a/compiler/driver/dex_compilation_unit.cc b/compiler/driver/dex_compilation_unit.cc
index 7e8e812..47b1929 100644
--- a/compiler/driver/dex_compilation_unit.cc
+++ b/compiler/driver/dex_compilation_unit.cc
@@ -21,7 +21,7 @@
namespace art {
-DexCompilationUnit::DexCompilationUnit(Handle<mirror::ClassLoader> class_loader,
+DexCompilationUnit::DexCompilationUnit(jobject class_loader,
ClassLinker* class_linker,
const DexFile& dex_file,
const DexFile::CodeItem* code_item,
diff --git a/compiler/driver/dex_compilation_unit.h b/compiler/driver/dex_compilation_unit.h
index 24a9a5b..854927d 100644
--- a/compiler/driver/dex_compilation_unit.h
+++ b/compiler/driver/dex_compilation_unit.h
@@ -34,7 +34,7 @@
class DexCompilationUnit : public DeletableArenaObject<kArenaAllocMisc> {
public:
- DexCompilationUnit(Handle<mirror::ClassLoader> class_loader,
+ DexCompilationUnit(jobject class_loader,
ClassLinker* class_linker,
const DexFile& dex_file,
const DexFile::CodeItem* code_item,
@@ -44,7 +44,7 @@
const VerifiedMethod* verified_method,
Handle<mirror::DexCache> dex_cache);
- Handle<mirror::ClassLoader> GetClassLoader() const {
+ jobject GetClassLoader() const {
return class_loader_;
}
@@ -113,7 +113,7 @@
}
private:
- const Handle<mirror::ClassLoader> class_loader_;
+ const jobject class_loader_;
ClassLinker* const class_linker_;
@@ -125,7 +125,7 @@
const uint32_t access_flags_;
const VerifiedMethod* verified_method_;
- const Handle<mirror::DexCache> dex_cache_;
+ Handle<mirror::DexCache> dex_cache_;
std::string symbol_;
};