Remove unassignable_types from vdex.
These were used in case a class went from "verified-at-runtime" to
"verified". With go/nterp, we're re not going to handle this situation
and we should only record what types the verifier expects to be
assignable.
Test: test.py
Bug: 112676029
Change-Id: I6ffa61cef3aa767dfccadbdfdd5432e72e143ca3
diff --git a/compiler/dex/verified_method.cc b/compiler/dex/verified_method.cc
index 172ec6b..d7dc310 100644
--- a/compiler/dex/verified_method.cc
+++ b/compiler/dex/verified_method.cc
@@ -92,9 +92,7 @@
DCHECK(cast_type.HasClass());
verifier::VerifierDeps::MaybeRecordAssignability(method_verifier->GetDexFile(),
cast_type.GetClass(),
- reg_type.GetClass(),
- /* is_strict= */ true,
- /* is_assignable= */ true);
+ reg_type.GetClass());
}
if (safe_cast_set_ == nullptr) {
safe_cast_set_.reset(new SafeCastSet());
diff --git a/dex2oat/verifier_deps_test.cc b/dex2oat/verifier_deps_test.cc
index 0e0ce91..c95a53e 100644
--- a/dex2oat/verifier_deps_test.cc
+++ b/dex2oat/verifier_deps_test.cc
@@ -199,10 +199,7 @@
VerifyWithCompilerDriver(/* verifier_deps= */ nullptr);
}
- bool TestAssignabilityRecording(const std::string& dst,
- const std::string& src,
- bool is_strict,
- bool is_assignable) {
+ bool TestAssignabilityRecording(const std::string& dst, const std::string& src) {
ScopedObjectAccess soa(Thread::Current());
LoadDexFile(soa);
StackHandleScope<1> hs(soa.Self());
@@ -212,9 +209,7 @@
DCHECK(klass_src != nullptr) << src;
verifier_deps_->AddAssignability(*primary_dex_file_,
klass_dst.Get(),
- klass_src,
- is_strict,
- is_assignable);
+ klass_src);
return true;
}
@@ -273,12 +268,10 @@
// Iterates over all assignability records and tries to find an entry which
// matches the expected destination/source pair.
bool HasAssignable(const std::string& expected_destination,
- const std::string& expected_source,
- bool expected_is_assignable) {
+ const std::string& expected_source) {
for (auto& dex_dep : verifier_deps_->dex_deps_) {
const DexFile& dex_file = *dex_dep.first;
- auto& storage = expected_is_assignable ? dex_dep.second->assignable_types_
- : dex_dep.second->unassignable_types_;
+ auto& storage = dex_dep.second->assignable_types_;
for (auto& entry : storage) {
std::string actual_destination =
verifier_deps_->GetStringFromId(dex_file, entry.GetDestination());
@@ -310,7 +303,6 @@
for (auto& entry : verifier_deps_->dex_deps_) {
has_strings |= !entry.second->strings_.empty();
has_assignability |= !entry.second->assignable_types_.empty();
- has_assignability |= !entry.second->unassignable_types_.empty();
has_verified_classes |= HasBoolValue(entry.second->verified_classes_, true);
has_unverified_classes |= HasBoolValue(entry.second->verified_classes_, false);
has_redefined_classes |= HasBoolValue(entry.second->redefined_classes_, true);
@@ -387,178 +379,125 @@
TEST_F(VerifierDepsTest, Assignable_BothInBoot) {
ASSERT_TRUE(TestAssignabilityRecording(/* dst= */ "Ljava/util/TimeZone;",
- /* src= */ "Ljava/util/SimpleTimeZone;",
- /* is_strict= */ true,
- /* is_assignable= */ true));
- ASSERT_TRUE(HasAssignable("Ljava/util/TimeZone;", "Ljava/util/SimpleTimeZone;", true));
+ /* src= */ "Ljava/util/SimpleTimeZone;"));
+ ASSERT_TRUE(HasAssignable("Ljava/util/TimeZone;", "Ljava/util/SimpleTimeZone;"));
}
TEST_F(VerifierDepsTest, Assignable_DestinationInBoot1) {
ASSERT_TRUE(TestAssignabilityRecording(/* dst= */ "Ljava/net/Socket;",
- /* src= */ "LMySSLSocket;",
- /* is_strict= */ true,
- /* is_assignable= */ true));
- ASSERT_TRUE(HasAssignable("Ljava/net/Socket;", "Ljavax/net/ssl/SSLSocket;", true));
+ /* src= */ "LMySSLSocket;"));
+ ASSERT_TRUE(HasAssignable("Ljava/net/Socket;", "Ljavax/net/ssl/SSLSocket;"));
}
TEST_F(VerifierDepsTest, Assignable_DestinationInBoot2) {
ASSERT_TRUE(TestAssignabilityRecording(/* dst= */ "Ljava/util/TimeZone;",
- /* src= */ "LMySimpleTimeZone;",
- /* is_strict= */ true,
- /* is_assignable= */ true));
- ASSERT_TRUE(HasAssignable("Ljava/util/TimeZone;", "Ljava/util/SimpleTimeZone;", true));
+ /* src= */ "LMySimpleTimeZone;"));
+ ASSERT_TRUE(HasAssignable("Ljava/util/TimeZone;", "Ljava/util/SimpleTimeZone;"));
}
TEST_F(VerifierDepsTest, Assignable_DestinationInBoot3) {
ASSERT_TRUE(TestAssignabilityRecording(/* dst= */ "Ljava/util/Collection;",
- /* src= */ "LMyThreadSet;",
- /* is_strict= */ true,
- /* is_assignable= */ true));
- ASSERT_TRUE(HasAssignable("Ljava/util/Collection;", "Ljava/util/Set;", true));
+ /* src= */ "LMyThreadSet;"));
+ ASSERT_TRUE(HasAssignable("Ljava/util/Collection;", "Ljava/util/Set;"));
}
TEST_F(VerifierDepsTest, Assignable_BothArrays_Resolved) {
ASSERT_TRUE(TestAssignabilityRecording(/* dst= */ "[[Ljava/util/TimeZone;",
- /* src= */ "[[Ljava/util/SimpleTimeZone;",
- /* is_strict= */ true,
- /* is_assignable= */ true));
+ /* src= */ "[[Ljava/util/SimpleTimeZone;"));
// If the component types of both arrays are resolved, we optimize the list of
// dependencies by recording a dependency on the component types.
- ASSERT_FALSE(HasAssignable("[[Ljava/util/TimeZone;", "[[Ljava/util/SimpleTimeZone;", true));
- ASSERT_FALSE(HasAssignable("[Ljava/util/TimeZone;", "[Ljava/util/SimpleTimeZone;", true));
- ASSERT_TRUE(HasAssignable("Ljava/util/TimeZone;", "Ljava/util/SimpleTimeZone;", true));
-}
-
-TEST_F(VerifierDepsTest, NotAssignable_BothInBoot) {
- ASSERT_TRUE(TestAssignabilityRecording(/* dst= */ "Ljava/lang/Exception;",
- /* src= */ "Ljava/util/SimpleTimeZone;",
- /* is_strict= */ true,
- /* is_assignable= */ false));
- ASSERT_TRUE(HasAssignable("Ljava/lang/Exception;", "Ljava/util/SimpleTimeZone;", false));
-}
-
-TEST_F(VerifierDepsTest, NotAssignable_DestinationInBoot1) {
- ASSERT_TRUE(TestAssignabilityRecording(/* dst= */ "Ljava/lang/Exception;",
- /* src= */ "LMySSLSocket;",
- /* is_strict= */ true,
- /* is_assignable= */ false));
- ASSERT_TRUE(HasAssignable("Ljava/lang/Exception;", "Ljavax/net/ssl/SSLSocket;", false));
-}
-
-TEST_F(VerifierDepsTest, NotAssignable_DestinationInBoot2) {
- ASSERT_TRUE(TestAssignabilityRecording(/* dst= */ "Ljava/lang/Exception;",
- /* src= */ "LMySimpleTimeZone;",
- /* is_strict= */ true,
- /* is_assignable= */ false));
- ASSERT_TRUE(HasAssignable("Ljava/lang/Exception;", "Ljava/util/SimpleTimeZone;", false));
-}
-
-TEST_F(VerifierDepsTest, NotAssignable_BothArrays) {
- ASSERT_TRUE(TestAssignabilityRecording(/* dst= */ "[Ljava/lang/Exception;",
- /* src= */ "[Ljava/util/SimpleTimeZone;",
- /* is_strict= */ true,
- /* is_assignable= */ false));
- ASSERT_TRUE(HasAssignable("Ljava/lang/Exception;", "Ljava/util/SimpleTimeZone;", false));
+ ASSERT_FALSE(HasAssignable("[[Ljava/util/TimeZone;", "[[Ljava/util/SimpleTimeZone;"));
+ ASSERT_FALSE(HasAssignable("[Ljava/util/TimeZone;", "[Ljava/util/SimpleTimeZone;"));
+ ASSERT_TRUE(HasAssignable("Ljava/util/TimeZone;", "Ljava/util/SimpleTimeZone;"));
}
TEST_F(VerifierDepsTest, ReturnType_Reference) {
ASSERT_TRUE(VerifyMethod("ReturnType_Reference"));
- ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "Ljava/lang/IllegalStateException;", true));
-}
-
-TEST_F(VerifierDepsTest, ReturnType_Array) {
- ASSERT_FALSE(VerifyMethod("ReturnType_Array"));
- ASSERT_TRUE(HasAssignable("Ljava/lang/Integer;", "Ljava/lang/IllegalStateException;", false));
+ ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "Ljava/lang/IllegalStateException;"));
}
TEST_F(VerifierDepsTest, InvokeArgumentType) {
ASSERT_TRUE(VerifyMethod("InvokeArgumentType"));
- ASSERT_TRUE(HasAssignable("Ljava/util/TimeZone;", "Ljava/util/SimpleTimeZone;", true));
+ ASSERT_TRUE(HasAssignable("Ljava/util/TimeZone;", "Ljava/util/SimpleTimeZone;"));
}
TEST_F(VerifierDepsTest, MergeTypes_RegisterLines) {
ASSERT_TRUE(VerifyMethod("MergeTypes_RegisterLines"));
- ASSERT_TRUE(HasAssignable("Ljava/lang/Exception;", "Ljava/net/SocketTimeoutException;", true));
+ ASSERT_TRUE(HasAssignable("Ljava/lang/Exception;", "Ljava/net/SocketTimeoutException;"));
ASSERT_TRUE(HasAssignable(
- "Ljava/lang/Exception;", "Ljava/util/concurrent/TimeoutException;", true));
+ "Ljava/lang/Exception;", "Ljava/util/concurrent/TimeoutException;"));
}
TEST_F(VerifierDepsTest, MergeTypes_IfInstanceOf) {
ASSERT_TRUE(VerifyMethod("MergeTypes_IfInstanceOf"));
- ASSERT_TRUE(HasAssignable("Ljava/lang/Exception;", "Ljava/net/SocketTimeoutException;", true));
+ ASSERT_TRUE(HasAssignable("Ljava/lang/Exception;", "Ljava/net/SocketTimeoutException;"));
ASSERT_TRUE(HasAssignable(
- "Ljava/lang/Exception;", "Ljava/util/concurrent/TimeoutException;", true));
- ASSERT_TRUE(HasAssignable("Ljava/net/SocketTimeoutException;", "Ljava/lang/Exception;", false));
+ "Ljava/lang/Exception;", "Ljava/util/concurrent/TimeoutException;"));
}
TEST_F(VerifierDepsTest, MergeTypes_Unresolved) {
ASSERT_TRUE(VerifyMethod("MergeTypes_Unresolved"));
- ASSERT_TRUE(HasAssignable("Ljava/lang/Exception;", "Ljava/net/SocketTimeoutException;", true));
+ ASSERT_TRUE(HasAssignable("Ljava/lang/Exception;", "Ljava/net/SocketTimeoutException;"));
ASSERT_TRUE(HasAssignable(
- "Ljava/lang/Exception;", "Ljava/util/concurrent/TimeoutException;", true));
+ "Ljava/lang/Exception;", "Ljava/util/concurrent/TimeoutException;"));
}
TEST_F(VerifierDepsTest, Throw) {
ASSERT_TRUE(VerifyMethod("Throw"));
- ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "Ljava/lang/IllegalStateException;", true));
+ ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "Ljava/lang/IllegalStateException;"));
}
TEST_F(VerifierDepsTest, MoveException_Resolved) {
ASSERT_TRUE(VerifyMethod("MoveException_Resolved"));
// Testing that all exception types are assignable to Throwable.
- ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "Ljava/io/InterruptedIOException;", true));
- ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "Ljava/net/SocketTimeoutException;", true));
- ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "Ljava/util/zip/ZipException;", true));
+ ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "Ljava/io/InterruptedIOException;"));
+ ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "Ljava/net/SocketTimeoutException;"));
+ ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "Ljava/util/zip/ZipException;"));
// Testing that the merge type is assignable to Throwable.
- ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "Ljava/io/IOException;", true));
+ ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "Ljava/io/IOException;"));
// Merging of exception types.
- ASSERT_TRUE(HasAssignable("Ljava/io/IOException;", "Ljava/io/InterruptedIOException;", true));
- ASSERT_TRUE(HasAssignable("Ljava/io/IOException;", "Ljava/util/zip/ZipException;", true));
+ ASSERT_TRUE(HasAssignable("Ljava/io/IOException;", "Ljava/io/InterruptedIOException;"));
+ ASSERT_TRUE(HasAssignable("Ljava/io/IOException;", "Ljava/util/zip/ZipException;"));
ASSERT_TRUE(HasAssignable(
- "Ljava/io/InterruptedIOException;", "Ljava/net/SocketTimeoutException;", true));
+ "Ljava/io/InterruptedIOException;", "Ljava/net/SocketTimeoutException;"));
}
TEST_F(VerifierDepsTest, InstanceField_Resolved_DeclaredInReferenced) {
ASSERT_TRUE(VerifyMethod("InstanceField_Resolved_DeclaredInReferenced"));
ASSERT_TRUE(HasAssignable(
- "Ljava/io/InterruptedIOException;", "Ljava/net/SocketTimeoutException;", true));
+ "Ljava/io/InterruptedIOException;", "Ljava/net/SocketTimeoutException;"));
}
TEST_F(VerifierDepsTest, InstanceField_Resolved_DeclaredInSuperclass1) {
ASSERT_TRUE(VerifyMethod("InstanceField_Resolved_DeclaredInSuperclass1"));
ASSERT_TRUE(HasAssignable(
- "Ljava/io/InterruptedIOException;", "Ljava/net/SocketTimeoutException;", true));
+ "Ljava/io/InterruptedIOException;", "Ljava/net/SocketTimeoutException;"));
}
TEST_F(VerifierDepsTest, InstanceField_Resolved_DeclaredInSuperclass2) {
ASSERT_TRUE(VerifyMethod("InstanceField_Resolved_DeclaredInSuperclass2"));
ASSERT_TRUE(HasAssignable(
- "Ljava/io/InterruptedIOException;", "Ljava/net/SocketTimeoutException;", true));
+ "Ljava/io/InterruptedIOException;", "Ljava/net/SocketTimeoutException;"));
}
TEST_F(VerifierDepsTest, InvokeVirtual_Resolved_DeclaredInReferenced) {
ASSERT_TRUE(VerifyMethod("InvokeVirtual_Resolved_DeclaredInReferenced"));
// Type dependency on `this` argument.
- ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "Ljava/net/SocketTimeoutException;", true));
+ ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "Ljava/net/SocketTimeoutException;"));
}
TEST_F(VerifierDepsTest, InvokeVirtual_Resolved_DeclaredInSuperclass1) {
ASSERT_TRUE(VerifyMethod("InvokeVirtual_Resolved_DeclaredInSuperclass1"));
// Type dependency on `this` argument.
- ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "Ljava/net/SocketTimeoutException;", true));
+ ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "Ljava/net/SocketTimeoutException;"));
}
TEST_F(VerifierDepsTest, InvokeSuper_ThisAssignable) {
ASSERT_TRUE(VerifyMethod("InvokeSuper_ThisAssignable"));
- ASSERT_TRUE(HasAssignable("Ljava/lang/Runnable;", "Ljava/lang/Thread;", true));
-}
-
-TEST_F(VerifierDepsTest, InvokeSuper_ThisNotAssignable) {
- ASSERT_FALSE(VerifyMethod("InvokeSuper_ThisNotAssignable"));
- ASSERT_TRUE(HasAssignable("Ljava/lang/Integer;", "Ljava/lang/Thread;", false));
+ ASSERT_TRUE(HasAssignable("Ljava/lang/Runnable;", "Ljava/lang/Thread;"));
}
TEST_F(VerifierDepsTest, EncodeDecode) {
@@ -677,16 +616,6 @@
// Check that dependencies are satisfied after decoding `buffer`.
ASSERT_TRUE(RunValidation([](VerifierDeps::DexFileDeps&) {}, buffer, &error_msg))
<< error_msg;
-
- // Mess with the dependencies to make sure we catch any change and fail to verify.
- ASSERT_FALSE(RunValidation([](VerifierDeps::DexFileDeps& deps) {
- deps.assignable_types_.insert(*deps.unassignable_types_.begin());
- }, buffer, &error_msg));
-
- // Mess with the unassignable_types.
- ASSERT_FALSE(RunValidation([](VerifierDeps::DexFileDeps& deps) {
- deps.unassignable_types_.insert(*deps.assignable_types_.begin());
- }, buffer, &error_msg));
}
TEST_F(VerifierDepsTest, CompilerDriver) {
@@ -738,23 +667,11 @@
ASSERT_FALSE(buffer.empty());
}
-TEST_F(VerifierDepsTest, NotAssignable_InterfaceWithClassInBoot) {
- ASSERT_TRUE(TestAssignabilityRecording(/* dst= */ "Ljava/lang/Exception;",
- /* src= */ "LIface;",
- /* is_strict= */ true,
- /* is_assignable= */ false));
- ASSERT_TRUE(HasAssignable("Ljava/lang/Exception;", "LIface;", false));
-}
-
TEST_F(VerifierDepsTest, Assignable_Arrays) {
ASSERT_TRUE(TestAssignabilityRecording(/* dst= */ "[LIface;",
- /* src= */ "[LMyClassExtendingInterface;",
- /* is_strict= */ false,
- /* is_assignable= */ true));
+ /* src= */ "[LMyClassExtendingInterface;"));
ASSERT_FALSE(HasAssignable(
- "LIface;", "LMyClassExtendingInterface;", /* expected_is_assignable= */ true));
- ASSERT_FALSE(HasAssignable(
- "LIface;", "LMyClassExtendingInterface;", /* expected_is_assignable= */ false));
+ "LIface;", "LMyClassExtendingInterface;"));
}
} // namespace verifier
diff --git a/runtime/vdex_file.h b/runtime/vdex_file.h
index 98efaa1..a953235 100644
--- a/runtime/vdex_file.h
+++ b/runtime/vdex_file.h
@@ -114,8 +114,8 @@
static constexpr uint8_t kVdexMagic[] = { 'v', 'd', 'e', 'x' };
// The format version of the verifier deps header and the verifier deps.
- // Last update: Remove class/field/method resolution.
- static constexpr uint8_t kVerifierDepsVersion[] = { '0', '2', '2', '\0' };
+ // Last update: Remove unassignable types.
+ static constexpr uint8_t kVerifierDepsVersion[] = { '0', '2', '3', '\0' };
// The format version of the dex section header and the dex section, containing
// both the dex code and the quickening data.
diff --git a/runtime/verifier/reg_type-inl.h b/runtime/verifier/reg_type-inl.h
index 9e12d63..3c7ad03 100644
--- a/runtime/verifier/reg_type-inl.h
+++ b/runtime/verifier/reg_type-inl.h
@@ -115,9 +115,9 @@
bool result = lhs.GetClass()->IsAssignableFrom(rhs.GetClass());
// Record assignability dependency. The `verifier` is null during unit tests and
// VerifiedMethod::GenerateSafeCastSet.
- if (verifier != nullptr) {
+ if (verifier != nullptr && result) {
VerifierDeps::MaybeRecordAssignability(
- verifier->GetDexFile(), lhs.GetClass(), rhs.GetClass(), strict, result);
+ verifier->GetDexFile(), lhs.GetClass(), rhs.GetClass());
}
return result;
} else {
diff --git a/runtime/verifier/reg_type.cc b/runtime/verifier/reg_type.cc
index 2d17030..c313e90 100644
--- a/runtime/verifier/reg_type.cc
+++ b/runtime/verifier/reg_type.cc
@@ -903,14 +903,10 @@
if (verifier != nullptr) {
VerifierDeps::MaybeRecordAssignability(verifier->GetDexFile(),
join_class,
- GetClass(),
- /* is_strict= */ true,
- /* is_assignable= */ true);
+ GetClass());
VerifierDeps::MaybeRecordAssignability(verifier->GetDexFile(),
join_class,
- incoming_type.GetClass(),
- /* is_strict= */ true,
- /* is_assignable= */ true);
+ incoming_type.GetClass());
}
if (GetClass() == join_class && !IsPreciseReference()) {
return *this;
diff --git a/runtime/verifier/verifier_deps.cc b/runtime/verifier/verifier_deps.cc
index dd68416..1df5c02 100644
--- a/runtime/verifier/verifier_deps.cc
+++ b/runtime/verifier/verifier_deps.cc
@@ -68,7 +68,6 @@
// which should be the one passed as `this` in this method.
DCHECK(other_deps.strings_.empty());
my_deps->assignable_types_.merge(other_deps.assignable_types_);
- my_deps->unassignable_types_.merge(other_deps.unassignable_types_);
BitVectorOr(my_deps->verified_classes_, other_deps.verified_classes_);
BitVectorOr(my_deps->redefined_classes_, other_deps.redefined_classes_);
}
@@ -272,9 +271,7 @@
void VerifierDeps::AddAssignability(const DexFile& dex_file,
ObjPtr<mirror::Class> destination,
- ObjPtr<mirror::Class> source,
- bool is_strict,
- bool is_assignable) {
+ ObjPtr<mirror::Class> source) {
// Test that the method is only called on reference types.
// Note that concurrent verification of `destination` and `source` may have
// set their status to erroneous. However, the tests performed below rely
@@ -291,17 +288,8 @@
return;
}
- if (source->IsObjectClass() && !is_assignable) {
- // j.l.Object is trivially non-assignable to other types, don't
- // record it.
- return;
- }
-
- if (destination == source ||
- destination->IsObjectClass() ||
- (!is_strict && destination->IsInterface())) {
+ if (destination == source || destination->IsObjectClass()) {
// Cases when `destination` is trivially assignable from `source`.
- DCHECK(is_assignable);
return;
}
@@ -317,15 +305,9 @@
if (destination_component->IsResolved() && source_component->IsResolved()) {
AddAssignability(dex_file,
destination_component,
- source_component,
- /* is_strict= */ true,
- is_assignable);
+ source_component);
return;
}
- } else {
- // We only do this check for non-array types, as arrays might have erroneous
- // component types which makes the IsAssignableFrom check unreliable.
- DCHECK_EQ(is_assignable, destination->IsAssignableFrom(source));
}
DexFileDeps* dex_deps = GetDexFileDeps(dex_file);
@@ -352,7 +334,7 @@
if (source == destination) {
return;
}
- } else if (is_assignable) {
+ } else {
source = FindOneClassPathBoundaryForInterface(destination, source);
if (source == nullptr) {
// There was no classpath boundary, no need to record.
@@ -367,11 +349,7 @@
dex::StringIndex destination_id = GetClassDescriptorStringId(dex_file, destination);
dex::StringIndex source_id = GetClassDescriptorStringId(dex_file, source);
- if (is_assignable) {
- dex_deps->assignable_types_.emplace(TypeAssignability(destination_id, source_id));
- } else {
- dex_deps->unassignable_types_.emplace(TypeAssignability(destination_id, source_id));
- }
+ dex_deps->assignable_types_.emplace(TypeAssignability(destination_id, source_id));
}
void VerifierDeps::MaybeRecordClassRedefinition(const DexFile& dex_file,
@@ -405,12 +383,10 @@
void VerifierDeps::MaybeRecordAssignability(const DexFile& dex_file,
ObjPtr<mirror::Class> destination,
- ObjPtr<mirror::Class> source,
- bool is_strict,
- bool is_assignable) {
+ ObjPtr<mirror::Class> source) {
VerifierDeps* thread_deps = GetThreadLocalVerifierDeps();
if (thread_deps != nullptr) {
- thread_deps->AddAssignability(dex_file, destination, source, is_strict, is_assignable);
+ thread_deps->AddAssignability(dex_file, destination, source);
}
}
@@ -579,7 +555,6 @@
const DexFileDeps& deps = *GetDexFileDeps(*dex_file);
EncodeStringVector(buffer, deps.strings_);
EncodeSet(buffer, deps.assignable_types_);
- EncodeSet(buffer, deps.unassignable_types_);
EncodeUint16SparseBitVector(buffer, deps.verified_classes_, /* sparse_value= */ false);
EncodeUint16SparseBitVector(buffer, deps.redefined_classes_, /* sparse_value= */ true);
}
@@ -595,8 +570,6 @@
data_start, data_end, &deps.strings_) &&
DecodeSet</*kFillSet=*/ !kOnlyVerifiedClasses>(
data_start, data_end, &deps.assignable_types_) &&
- DecodeSet</*kFillSet=*/ !kOnlyVerifiedClasses>(
- data_start, data_end, &deps.unassignable_types_) &&
DecodeUint16SparseBitVector</*kFillVector=*/ true>(
data_start, data_end, num_class_defs, /*sparse_value=*/ false, &deps.verified_classes_) &&
DecodeUint16SparseBitVector</*kFillVector=*/ !kOnlyVerifiedClasses>(
@@ -686,7 +659,6 @@
bool VerifierDeps::DexFileDeps::Equals(const VerifierDeps::DexFileDeps& rhs) const {
return (strings_ == rhs.strings_) &&
(assignable_types_ == rhs.assignable_types_) &&
- (unassignable_types_ == rhs.unassignable_types_) &&
(verified_classes_ == rhs.verified_classes_);
}
@@ -725,14 +697,6 @@
<< "\n";
}
- for (const TypeAssignability& entry : dep.second->unassignable_types_) {
- vios->Stream()
- << GetStringFromId(dex_file, entry.GetSource())
- << " must not be assignable to "
- << GetStringFromId(dex_file, entry.GetDestination())
- << "\n";
- }
-
for (size_t idx = 0; idx < dep.second->verified_classes_.size(); idx++) {
if (!dep.second->verified_classes_[idx]) {
vios->Stream()
@@ -878,12 +842,6 @@
deps.assignable_types_,
/* expected_assignability= */ true,
self,
- error_msg) &&
- VerifyAssignability(class_loader,
- dex_file,
- deps.unassignable_types_,
- /* expected_assignability= */ false,
- self,
error_msg);
}
diff --git a/runtime/verifier/verifier_deps.h b/runtime/verifier/verifier_deps.h
index 15fb4a5..b11ccb6 100644
--- a/runtime/verifier/verifier_deps.h
+++ b/runtime/verifier/verifier_deps.h
@@ -89,9 +89,7 @@
// owner of the method for which MethodVerifier performed the assignability test.
static void MaybeRecordAssignability(const DexFile& dex_file,
ObjPtr<mirror::Class> destination,
- ObjPtr<mirror::Class> source,
- bool is_strict,
- bool is_assignable)
+ ObjPtr<mirror::Class> source)
REQUIRES_SHARED(Locks::mutator_lock_)
REQUIRES(!Locks::verifier_deps_lock_);
@@ -155,7 +153,6 @@
// Set of class pairs recording the outcome of assignability test from one
// of the two types to the other.
std::set<TypeAssignability> assignable_types_;
- std::set<TypeAssignability> unassignable_types_;
// Bit vector indexed by class def indices indicating whether the corresponding
// class was successfully verified.
@@ -213,9 +210,7 @@
void AddAssignability(const DexFile& dex_file,
ObjPtr<mirror::Class> destination,
- ObjPtr<mirror::Class> source,
- bool is_strict,
- bool is_assignable)
+ ObjPtr<mirror::Class> source)
REQUIRES_SHARED(Locks::mutator_lock_);
bool Equals(const VerifierDeps& rhs) const;