summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--dex2oat/driver/compiler_driver.cc1
-rw-r--r--openjdkjvmti/ti_redefine.cc72
-rw-r--r--openjdkjvmti/ti_redefine.h10
-rw-r--r--runtime/class_linker.cc9
-rw-r--r--runtime/verifier/class_verifier.cc244
-rw-r--r--runtime/verifier/class_verifier.h48
-rw-r--r--runtime/verifier/method_verifier_test.cc10
-rw-r--r--tools/art_verifier/art_verifier.cc10
8 files changed, 72 insertions, 332 deletions
diff --git a/dex2oat/driver/compiler_driver.cc b/dex2oat/driver/compiler_driver.cc
index cc9f9ec450..e1f51437ce 100644
--- a/dex2oat/driver/compiler_driver.cc
+++ b/dex2oat/driver/compiler_driver.cc
@@ -1846,6 +1846,7 @@ class VerifyClassVisitor : public CompilationVisitor {
verifier::ClassVerifier::VerifyClass(soa.Self(),
soa.Self()->GetVerifierDeps(),
&dex_file,
+ klass,
dex_cache,
class_loader,
class_def,
diff --git a/openjdkjvmti/ti_redefine.cc b/openjdkjvmti/ti_redefine.cc
index 65bfc15b04..0289a7b934 100644
--- a/openjdkjvmti/ti_redefine.cc
+++ b/openjdkjvmti/ti_redefine.cc
@@ -1608,13 +1608,16 @@ RedefinitionDataIter RedefinitionDataHolder::end() {
bool Redefiner::ClassRedefinition::CheckVerification(const RedefinitionDataIter& iter) {
DCHECK_EQ(dex_file_->NumClassDefs(), 1u);
- art::StackHandleScope<2> hs(driver_->self_);
+ art::StackHandleScope<3> hs(driver_->self_);
std::string error;
// TODO Make verification log level lower
art::verifier::FailureKind failure =
art::verifier::ClassVerifier::VerifyClass(driver_->self_,
/*verifier_deps=*/nullptr,
dex_file_.get(),
+ hs.NewHandle(iter.GetNewClassObject() != nullptr
+ ? iter.GetNewClassObject()
+ : iter.GetMirrorClass()),
hs.NewHandle(iter.GetNewDexCache()),
hs.NewHandle(GetClassLoader()),
/*class_def=*/ dex_file_->GetClassDef(0),
@@ -1624,24 +1627,11 @@ bool Redefiner::ClassRedefinition::CheckVerification(const RedefinitionDataIter&
art::verifier::HardFailLogMode::kLogWarning,
art::Runtime::Current()->GetTargetSdkVersion(),
&error);
- switch (failure) {
- case art::verifier::FailureKind::kNoFailure:
- // TODO It is possible that by doing redefinition previous NO_COMPILE verification failures
- // were fixed. It would be nice to reflect this in the new implementations.
- return true;
- case art::verifier::FailureKind::kSoftFailure:
- case art::verifier::FailureKind::kAccessChecksFailure:
- case art::verifier::FailureKind::kTypeChecksFailure:
- // Soft failures might require interpreter on some methods. It won't prevent redefinition but
- // it does mean we need to run the verifier again and potentially update method flags after
- // performing the swap.
- needs_reverify_ = true;
- return true;
- case art::verifier::FailureKind::kHardFailure: {
- RecordFailure(ERR(FAILS_VERIFICATION), "Failed to verify class. Error was: " + error);
- return false;
- }
+ if (failure == art::verifier::FailureKind::kHardFailure) {
+ RecordFailure(ERR(FAILS_VERIFICATION), "Failed to verify class. Error was: " + error);
+ return false;
}
+ return true;
}
// Looks through the previously allocated cookies to see if we need to update them with another new
@@ -2519,36 +2509,9 @@ jvmtiError Redefiner::Run() {
// owns the DexFile and when ownership is transferred.
ReleaseAllDexFiles();
}
- // By now the class-linker knows about all the classes so we can safetly retry verification and
- // update method flags.
- ReverifyClasses(holder);
return OK;
}
-void Redefiner::ReverifyClasses(RedefinitionDataHolder& holder) {
- for (RedefinitionDataIter data = holder.begin(); data != holder.end(); ++data) {
- data.GetRedefinition().ReverifyClass(data);
- }
-}
-
-void Redefiner::ClassRedefinition::ReverifyClass(const RedefinitionDataIter &cur_data) {
- if (!needs_reverify_) {
- return;
- }
- VLOG(plugin) << "Reverifying " << class_sig_ << " due to soft failures";
- std::string error;
- // TODO Make verification log level lower
- art::verifier::FailureKind failure =
- art::verifier::ClassVerifier::ReverifyClass(driver_->self_,
- cur_data.GetMirrorClass(),
- /*log_level=*/
- art::verifier::HardFailLogMode::kLogWarning,
- /*api_level=*/
- art::Runtime::Current()->GetTargetSdkVersion(),
- &error);
- CHECK_NE(failure, art::verifier::FailureKind::kHardFailure);
-}
-
void Redefiner::ClassRedefinition::UpdateMethods(art::ObjPtr<art::mirror::Class> mclass,
const art::dex::ClassDef& class_def) {
art::ClassLinker* linker = driver_->runtime_->GetClassLinker();
@@ -3050,25 +3013,6 @@ void Redefiner::ClassRedefinition::UpdateClass(const RedefinitionDataIter& holde
} else if (!holder.IsActuallyStructural()) {
UpdateClassInPlace(holder);
}
- UpdateClassCommon(holder);
-}
-
-void Redefiner::ClassRedefinition::UpdateClassCommon(const RedefinitionDataIter &cur_data) {
- // NB This is after we've already replaced all old-refs with new-refs in the structural case.
- art::ObjPtr<art::mirror::Class> klass(cur_data.GetMirrorClass());
- DCHECK(!IsStructuralRedefinition() || klass == cur_data.GetNewClassObject());
- if (!needs_reverify_) {
- return;
- }
- // Force the most restrictive interpreter environment. We don't know what the final verification
- // will allow. We will clear these after retrying verification once we drop the mutator-lock.
- klass->VisitMethods([](art::ArtMethod* m) REQUIRES_SHARED(art::Locks::mutator_lock_) {
- if (!m->IsNative() && m->IsInvokable() && !m->IsObsolete()) {
- m->ClearSkipAccessChecks();
- m->SetDontCompile();
- m->SetMustCountLocks();
- }
- }, art::kRuntimePointerSize);
}
// Restores the old obsolete methods maps if it turns out they weren't needed (ie there were no new
diff --git a/openjdkjvmti/ti_redefine.h b/openjdkjvmti/ti_redefine.h
index d7c7b89899..76de9a7bed 100644
--- a/openjdkjvmti/ti_redefine.h
+++ b/openjdkjvmti/ti_redefine.h
@@ -240,12 +240,6 @@ class Redefiner {
void UpdateClass(const RedefinitionDataIter& cur_data)
REQUIRES(art::Locks::mutator_lock_);
- void UpdateClassCommon(const RedefinitionDataIter& cur_data)
- REQUIRES(art::Locks::mutator_lock_);
-
- void ReverifyClass(const RedefinitionDataIter& cur_data)
- REQUIRES_SHARED(art::Locks::mutator_lock_);
-
void CollectNewFieldAndMethodMappings(const RedefinitionDataIter& data,
std::map<art::ArtMethod*, art::ArtMethod*>* method_map,
std::map<art::ArtField*, art::ArtField*>* field_map)
@@ -292,10 +286,6 @@ class Redefiner {
bool added_fields_ = false;
bool added_methods_ = false;
bool has_virtuals_ = false;
-
- // Does the class need to be reverified due to verification soft-fails possibly forcing
- // interpreter or lock-counting?
- bool needs_reverify_ = false;
};
ArtJvmTiEnv* env_;
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index f842265d29..719f0caad8 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -4744,9 +4744,16 @@ verifier::FailureKind ClassLinker::PerformClassVerification(Thread* self,
verifier::HardFailLogMode log_level,
std::string* error_msg) {
Runtime* const runtime = Runtime::Current();
+ StackHandleScope<2> hs(self);
+ Handle<mirror::DexCache> dex_cache(hs.NewHandle(klass->GetDexCache()));
+ Handle<mirror::ClassLoader> class_loader(hs.NewHandle(klass->GetClassLoader()));
return verifier::ClassVerifier::VerifyClass(self,
verifier_deps,
- klass.Get(),
+ dex_cache->GetDexFile(),
+ klass,
+ dex_cache,
+ class_loader,
+ *klass->GetClassDef(),
runtime->GetCompilerCallbacks(),
runtime->IsAotCompiler(),
log_level,
diff --git a/runtime/verifier/class_verifier.cc b/runtime/verifier/class_verifier.cc
index 7e0ed1edea..1c8142b642 100644
--- a/runtime/verifier/class_verifier.cc
+++ b/runtime/verifier/class_verifier.cc
@@ -51,202 +51,39 @@ using android::base::StringPrintf;
// sure we only print this once.
static bool gPrintedDxMonitorText = false;
-// A class used by the verifier to tell users about what options need to be set for given methods.
-class VerifierCallback {
- public:
- virtual ~VerifierCallback() {}
- virtual void SetDontCompile(ArtMethod* method, bool value)
- REQUIRES_SHARED(Locks::mutator_lock_) = 0;
- virtual void SetMustCountLocks(ArtMethod* method, bool value)
- REQUIRES_SHARED(Locks::mutator_lock_) = 0;
-};
-
-class StandardVerifyCallback : public VerifierCallback {
- public:
- void SetDontCompile(ArtMethod* m, bool value) override REQUIRES_SHARED(Locks::mutator_lock_) {
- if (value) {
- m->SetDontCompile();
- }
- }
- void SetMustCountLocks(ArtMethod* m, bool value) override REQUIRES_SHARED(Locks::mutator_lock_) {
- if (value) {
- m->SetMustCountLocks();
- }
- }
-};
-
-FailureKind ClassVerifier::ReverifyClass(Thread* self,
- ObjPtr<mirror::Class> klass,
- HardFailLogMode log_level,
- uint32_t api_level,
- std::string* error) {
- DCHECK(!Runtime::Current()->IsAotCompiler());
- StackHandleScope<1> hs(self);
- Handle<mirror::Class> h_klass(hs.NewHandle(klass));
- // We don't want to mess with these while other mutators are possibly looking at them. Instead we
- // will wait until we can update them while everything is suspended.
- class DelayedVerifyCallback : public VerifierCallback {
- public:
- void SetDontCompile(ArtMethod* m, bool value) override REQUIRES_SHARED(Locks::mutator_lock_) {
- dont_compiles_.push_back({ m, value });
- }
- void SetMustCountLocks(ArtMethod* m, bool value) override
- REQUIRES_SHARED(Locks::mutator_lock_) {
- count_locks_.push_back({ m, value });
- }
- void UpdateFlags(bool skip_access_checks) REQUIRES(Locks::mutator_lock_) {
- for (auto it : count_locks_) {
- VLOG(verifier_debug) << "Setting " << it.first->PrettyMethod() << " count locks to "
- << it.second;
- if (it.second) {
- it.first->SetMustCountLocks();
- } else {
- it.first->ClearMustCountLocks();
- }
- if (skip_access_checks && it.first->IsInvokable() && !it.first->IsNative()) {
- it.first->SetSkipAccessChecks();
- }
- }
- for (auto it : dont_compiles_) {
- VLOG(verifier_debug) << "Setting " << it.first->PrettyMethod() << " dont-compile to "
- << it.second;
- if (it.second) {
- it.first->SetDontCompile();
- } else {
- it.first->ClearDontCompile();
- }
- }
- }
-
- private:
- std::vector<std::pair<ArtMethod*, bool>> dont_compiles_;
- std::vector<std::pair<ArtMethod*, bool>> count_locks_;
- };
- DelayedVerifyCallback dvc;
- FailureKind res = CommonVerifyClass(self,
- /*verifier_deps=*/nullptr,
- h_klass.Get(),
- /*callbacks=*/nullptr,
- &dvc,
- /*allow_soft_failures=*/false,
- log_level,
- api_level,
- error);
- DCHECK_NE(res, FailureKind::kHardFailure);
- ScopedThreadSuspension sts(Thread::Current(), ThreadState::kSuspended);
- ScopedSuspendAll ssa("Update method flags for reverify");
- dvc.UpdateFlags(res == FailureKind::kNoFailure);
- return res;
-}
-
-FailureKind ClassVerifier::VerifyClass(Thread* self,
- VerifierDeps* verifier_deps,
- ObjPtr<mirror::Class> klass,
- CompilerCallbacks* callbacks,
- bool allow_soft_failures,
- HardFailLogMode log_level,
- uint32_t api_level,
- std::string* error) {
- if (klass->IsVerified()) {
- return FailureKind::kNoFailure;
+static void UpdateMethodFlags(uint32_t method_index,
+ Handle<mirror::Class> klass,
+ Handle<mirror::DexCache> dex_cache,
+ int error_types)
+ REQUIRES_SHARED(Locks::mutator_lock_) {
+ if (klass == nullptr) {
+ DCHECK(Runtime::Current()->IsAotCompiler());
+ // Flags will be set at runtime.
+ return;
}
- StandardVerifyCallback svc;
- return CommonVerifyClass(self,
- verifier_deps,
- klass,
- callbacks,
- &svc,
- allow_soft_failures,
- log_level,
- api_level,
- error);
-}
-FailureKind ClassVerifier::CommonVerifyClass(Thread* self,
- VerifierDeps* verifier_deps,
- ObjPtr<mirror::Class> klass,
- CompilerCallbacks* callbacks,
- VerifierCallback* verifier_callback,
- bool allow_soft_failures,
- HardFailLogMode log_level,
- uint32_t api_level,
- std::string* error) {
- bool early_failure = false;
- std::string failure_message;
- const DexFile& dex_file = klass->GetDexFile();
- const dex::ClassDef* class_def = klass->GetClassDef();
- ObjPtr<mirror::Class> super = klass->GetSuperClass();
- std::string temp;
- if (super == nullptr && strcmp("Ljava/lang/Object;", klass->GetDescriptor(&temp)) != 0) {
- early_failure = true;
- failure_message = " that has no super class";
- } else if (super != nullptr && super->IsFinal()) {
- early_failure = true;
- failure_message = " that attempts to sub-class final class " + super->PrettyDescriptor();
- } else if (class_def == nullptr) {
- early_failure = true;
- failure_message = " that isn't present in dex file " + dex_file.GetLocation();
+ // Mark methods with DontCompile/MustCountLocks flags.
+ ClassLinker* const linker = Runtime::Current()->GetClassLinker();
+ ArtMethod* method =
+ klass->FindClassMethod(dex_cache.Get(), method_index, linker->GetImagePointerSize());
+ DCHECK(method != nullptr);
+ DCHECK(method->GetDeclaringClass() == klass.Get());
+ if (!CanCompilerHandleVerificationFailure(error_types)) {
+ method->SetDontCompile();
}
- if (early_failure) {
- *error = "Verifier rejected class " + klass->PrettyDescriptor() + failure_message;
- if (callbacks != nullptr) {
- ClassReference ref(&dex_file, klass->GetDexClassDefIndex());
- callbacks->ClassRejected(ref);
- }
- return FailureKind::kHardFailure;
+ if ((error_types & VerifyError::VERIFY_ERROR_LOCKING) != 0) {
+ method->SetMustCountLocks();
}
- StackHandleScope<2> hs(self);
- Handle<mirror::DexCache> dex_cache(hs.NewHandle(klass->GetDexCache()));
- Handle<mirror::ClassLoader> class_loader(hs.NewHandle(klass->GetClassLoader()));
- return VerifyClass(self,
- verifier_deps,
- &dex_file,
- dex_cache,
- class_loader,
- *class_def,
- callbacks,
- verifier_callback,
- allow_soft_failures,
- log_level,
- api_level,
- error);
-}
-
-
-FailureKind ClassVerifier::VerifyClass(Thread* self,
- VerifierDeps* verifier_deps,
- const DexFile* dex_file,
- Handle<mirror::DexCache> dex_cache,
- Handle<mirror::ClassLoader> class_loader,
- const dex::ClassDef& class_def,
- CompilerCallbacks* callbacks,
- bool allow_soft_failures,
- HardFailLogMode log_level,
- uint32_t api_level,
- std::string* error) {
- StandardVerifyCallback svc;
- return VerifyClass(self,
- verifier_deps,
- dex_file,
- dex_cache,
- class_loader,
- class_def,
- callbacks,
- &svc,
- allow_soft_failures,
- log_level,
- api_level,
- error);
}
FailureKind ClassVerifier::VerifyClass(Thread* self,
VerifierDeps* verifier_deps,
const DexFile* dex_file,
+ Handle<mirror::Class> klass,
Handle<mirror::DexCache> dex_cache,
Handle<mirror::ClassLoader> class_loader,
const dex::ClassDef& class_def,
CompilerCallbacks* callbacks,
- VerifierCallback* verifier_callback,
bool allow_soft_failures,
HardFailLogMode log_level,
uint32_t api_level,
@@ -259,6 +96,9 @@ FailureKind ClassVerifier::VerifyClass(Thread* self,
return FailureKind::kHardFailure;
}
+ // Note that `klass` can be a redefined class, not in the loader's table yet.
+ // Therefore, we do not use it for class resolution, but only when needing to
+ // update its methods' flags.
ClassAccessor accessor(*dex_file, class_def);
SCOPED_TRACE << "VerifyClass " << PrettyDescriptor(accessor.GetDescriptor());
metrics::AutoTimer timer{GetMetrics()->ClassVerificationTotalTime()};
@@ -310,33 +150,19 @@ FailureKind ClassVerifier::VerifyClass(Thread* self,
*error += " ";
*error += hard_failure_msg;
} else if (result.kind != FailureKind::kNoFailure) {
- // Mark methods with DontCompile/MustCountLocks flags.
- const InvokeType type = method.GetInvokeType(class_def.access_flags_);
- ArtMethod* resolved_method = linker->ResolveMethod<ClassLinker::ResolveMode::kNoChecks>(
- method_idx, dex_cache, class_loader, /* referrer= */ nullptr, type);
- if (resolved_method == nullptr) {
- DCHECK(self->IsExceptionPending());
- // We couldn't resolve the method, but continue regardless.
- self->ClearException();
- } else {
- DCHECK(resolved_method->GetDeclaringClassUnchecked() != nullptr) << type;
- if (!CanCompilerHandleVerificationFailure(result.types)) {
- verifier_callback->SetDontCompile(resolved_method, true);
- }
- if ((result.types & VerifyError::VERIFY_ERROR_LOCKING) != 0) {
- verifier_callback->SetMustCountLocks(resolved_method, true);
- // Print a warning about expected slow-down.
- // Use a string temporary to print one contiguous warning.
- std::string tmp =
- StringPrintf("Method %s failed lock verification and will run slower.",
- resolved_method->PrettyMethod().c_str());
- if (!gPrintedDxMonitorText) {
- tmp = tmp + "\nCommon causes for lock verification issues are non-optimized dex code\n"
- "and incorrect proguard optimizations.";
- gPrintedDxMonitorText = true;
- }
- LOG(WARNING) << tmp;
+ UpdateMethodFlags(method.GetIndex(), klass, dex_cache, result.types);
+ if ((result.types & VerifyError::VERIFY_ERROR_LOCKING) != 0) {
+ // Print a warning about expected slow-down.
+ // Use a string temporary to print one contiguous warning.
+ std::string tmp =
+ StringPrintf("Method %s failed lock verification and will run slower.",
+ dex_file->PrettyMethod(method.GetIndex()).c_str());
+ if (!gPrintedDxMonitorText) {
+ tmp = tmp + "\nCommon causes for lock verification issues are non-optimized dex code\n"
+ "and incorrect proguard optimizations.";
+ gPrintedDxMonitorText = true;
}
+ LOG(WARNING) << tmp;
}
}
diff --git a/runtime/verifier/class_verifier.h b/runtime/verifier/class_verifier.h
index a81b0b86a8..26cdf2b8de 100644
--- a/runtime/verifier/class_verifier.h
+++ b/runtime/verifier/class_verifier.h
@@ -49,35 +49,17 @@ class ClassLoader;
namespace verifier {
-class VerifierCallback;
class VerifierDeps;
// Verifier that ensures the complete class is OK.
class ClassVerifier {
public:
- // Redo verification on a loaded class. This is for use by class redefinition. This must be called
- // with all methods already having all of kAccDontCompile and kAccCountLocks and not having
- // kAccSkipAccessChecks. This will remove some of these flags from the method. The caller must
- // ensure this cannot race with other changes to the verification class flags.
- static FailureKind ReverifyClass(Thread* self,
- ObjPtr<mirror::Class> klass,
- HardFailLogMode log_level,
- uint32_t api_level,
- std::string* error)
- REQUIRES_SHARED(Locks::mutator_lock_);
- // Verify a class. Returns "kNoFailure" on success.
- static FailureKind VerifyClass(Thread* self,
- VerifierDeps* verifier_deps,
- ObjPtr<mirror::Class> klass,
- CompilerCallbacks* callbacks,
- bool allow_soft_failures,
- HardFailLogMode log_level,
- uint32_t api_level,
- std::string* error)
- REQUIRES_SHARED(Locks::mutator_lock_);
+ // The main entrypoint for class verification. During AOT, `klass` can be
+ // null.
static FailureKind VerifyClass(Thread* self,
VerifierDeps* verifier_deps,
const DexFile* dex_file,
+ Handle<mirror::Class> klass,
Handle<mirror::DexCache> dex_cache,
Handle<mirror::ClassLoader> class_loader,
const dex::ClassDef& class_def,
@@ -95,30 +77,6 @@ class ClassVerifier {
REQUIRES_SHARED(Locks::mutator_lock_);
private:
- static FailureKind CommonVerifyClass(Thread* self,
- VerifierDeps* verifier_deps,
- ObjPtr<mirror::Class> klass,
- CompilerCallbacks* callbacks,
- VerifierCallback* verifier_callback,
- bool allow_soft_failures,
- HardFailLogMode log_level,
- uint32_t api_level,
- std::string* error)
- REQUIRES_SHARED(Locks::mutator_lock_);
-
- static FailureKind VerifyClass(Thread* self,
- VerifierDeps* verifier_deps,
- const DexFile* dex_file,
- Handle<mirror::DexCache> dex_cache,
- Handle<mirror::ClassLoader> class_loader,
- const dex::ClassDef& class_def,
- CompilerCallbacks* callbacks,
- VerifierCallback* verifier_callback,
- bool allow_soft_failures,
- HardFailLogMode log_level,
- uint32_t api_level,
- std::string* error)
- REQUIRES_SHARED(Locks::mutator_lock_);
DISALLOW_COPY_AND_ASSIGN(ClassVerifier);
};
diff --git a/runtime/verifier/method_verifier_test.cc b/runtime/verifier/method_verifier_test.cc
index 976198240b..aa794704c5 100644
--- a/runtime/verifier/method_verifier_test.cc
+++ b/runtime/verifier/method_verifier_test.cc
@@ -41,13 +41,21 @@ class MethodVerifierTest : public CommonRuntimeTest {
REQUIRES_SHARED(Locks::mutator_lock_) {
ASSERT_FALSE(descriptor.empty());
Thread* self = Thread::Current();
- ObjPtr<mirror::Class> klass = class_linker_->FindSystemClass(self, descriptor.c_str());
+ StackHandleScope<3> hs(self);
+ Handle<mirror::Class> klass(
+ hs.NewHandle(class_linker_->FindSystemClass(self, descriptor.c_str())));
+ Handle<mirror::DexCache> dex_cache(hs.NewHandle(klass->GetDexCache()));
+ Handle<mirror::ClassLoader> loader(hs.NewHandle(klass->GetClassLoader()));
// Verify the class
std::string error_msg;
FailureKind failure = ClassVerifier::VerifyClass(self,
/* verifier_deps= */ nullptr,
+ dex_cache->GetDexFile(),
klass,
+ dex_cache,
+ loader,
+ *klass->GetClassDef(),
nullptr,
true,
HardFailLogMode::kLogWarning,
diff --git a/tools/art_verifier/art_verifier.cc b/tools/art_verifier/art_verifier.cc
index 313c4705d4..98935a2b4c 100644
--- a/tools/art_verifier/art_verifier.cc
+++ b/tools/art_verifier/art_verifier.cc
@@ -214,10 +214,11 @@ struct MethodVerifierMain : public CmdlineMain<MethodVerifierArgs> {
jobject class_loader = Install(runtime, unique_dex_files, &dex_files);
CHECK(class_loader != nullptr);
- StackHandleScope<2> scope(soa.Self());
+ StackHandleScope<3> scope(soa.Self());
Handle<mirror::ClassLoader> h_loader = scope.NewHandle(
soa.Decode<mirror::ClassLoader>(class_loader));
MutableHandle<mirror::Class> h_klass(scope.NewHandle<mirror::Class>(nullptr));
+ MutableHandle<mirror::DexCache> h_dex_cache(scope.NewHandle<mirror::DexCache>(nullptr));
if (args_->method_verifier_verbose_) {
gLogVerbosity.verifier = true;
@@ -244,11 +245,16 @@ struct MethodVerifierMain : public CmdlineMain<MethodVerifierArgs> {
soa.Self()->ClearException();
continue;
}
+ h_dex_cache.Assign(h_klass->GetDexCache());
std::string error_msg;
verifier::FailureKind res =
verifier::ClassVerifier::VerifyClass(soa.Self(),
/* verifier_deps= */ nullptr,
- h_klass.Get(),
+ h_dex_cache->GetDexFile(),
+ h_klass,
+ h_dex_cache,
+ h_loader,
+ *h_klass->GetClassDef(),
runtime->GetCompilerCallbacks(),
true,
verifier::HardFailLogMode::kLogWarning,