Filter image classes in RecordImageClassesVisitor.
We were previously filtering them only in ClinitImageUpdate.
However, for --compiler-filter=assume-verified we take an
early exit from CompilerDriver::PreCompile() and do not
reach that code, so we need to filter in both places.
Test: Manual, extract the dex2oat command for the framework
extension compilation from build logs and run it with
--compiler-filter=assume-verified.
Bug: 119868597
Change-Id: If82bc433828fc825cf5792e125a55bbc42cfccbb
diff --git a/dex2oat/driver/compiler_driver.cc b/dex2oat/driver/compiler_driver.cc
index 365edd6..e7c0c1e 100644
--- a/dex2oat/driver/compiler_driver.cc
+++ b/dex2oat/driver/compiler_driver.cc
@@ -1017,14 +1017,40 @@
std::vector<ObjPtr<mirror::Class>> classes_;
};
+static inline bool CanIncludeInCurrentImage(ObjPtr<mirror::Class> klass)
+ REQUIRES_SHARED(Locks::mutator_lock_) {
+ DCHECK(klass != nullptr);
+ gc::Heap* heap = Runtime::Current()->GetHeap();
+ if (heap->GetBootImageSpaces().empty()) {
+ return true; // We can include any class when compiling the primary boot image.
+ }
+ if (heap->ObjectIsInBootImageSpace(klass)) {
+ return false; // Already included in the boot image we're compiling against.
+ }
+ return AotClassLinker::CanReferenceInBootImageExtension(klass, heap);
+}
+
class RecordImageClassesVisitor : public ClassVisitor {
public:
explicit RecordImageClassesVisitor(HashSet<std::string>* image_classes)
: image_classes_(image_classes) {}
bool operator()(ObjPtr<mirror::Class> klass) override REQUIRES_SHARED(Locks::mutator_lock_) {
+ bool resolved = klass->IsResolved();
+ DCHECK(resolved || klass->IsErroneousUnresolved());
+ bool can_include_in_image = LIKELY(resolved) && CanIncludeInCurrentImage(klass);
std::string temp;
- image_classes_->insert(klass->GetDescriptor(&temp));
+ std::string_view descriptor(klass->GetDescriptor(&temp));
+ if (can_include_in_image) {
+ image_classes_->insert(std::string(descriptor)); // Does nothing if already present.
+ } else {
+ auto it = image_classes_->find(descriptor);
+ if (it != image_classes_->end()) {
+ VLOG(compiler) << "Removing " << (resolved ? "unsuitable" : "unresolved")
+ << " class from image classes: " << descriptor;
+ image_classes_->erase(it);
+ }
+ }
return true;
}
@@ -1106,7 +1132,9 @@
RecordImageClassesVisitor visitor(image_classes);
class_linker->VisitClasses(&visitor);
- CHECK(!image_classes->empty());
+ if (GetCompilerOptions().IsBootImage()) {
+ CHECK(!image_classes->empty());
+ }
}
static void MaybeAddToImageClasses(Thread* self,
@@ -1212,14 +1240,14 @@
DCHECK(resolved || klass->IsErroneousUnresolved());
bool can_include_in_image = LIKELY(resolved) && CanIncludeInCurrentImage(klass);
std::string temp;
- std::string_view name(klass->GetDescriptor(&temp));
- auto it = data_->image_class_descriptors_->find(name);
+ std::string_view descriptor(klass->GetDescriptor(&temp));
+ auto it = data_->image_class_descriptors_->find(descriptor);
if (it != data_->image_class_descriptors_->end()) {
if (can_include_in_image) {
data_->image_classes_.push_back(data_->hs_.NewHandle(klass));
} else {
VLOG(compiler) << "Removing " << (resolved ? "unsuitable" : "unresolved")
- << " class from image classes: " << name;
+ << " class from image classes: " << descriptor;
data_->image_class_descriptors_->erase(it);
}
} else if (can_include_in_image) {
@@ -1264,19 +1292,6 @@
}
}
- static bool CanIncludeInCurrentImage(ObjPtr<mirror::Class> klass)
- REQUIRES_SHARED(Locks::mutator_lock_) {
- DCHECK(klass != nullptr);
- gc::Heap* heap = Runtime::Current()->GetHeap();
- if (heap->GetBootImageSpaces().empty()) {
- return true; // We can include any class when compiling the primary boot image.
- }
- if (heap->ObjectIsInBootImageSpace(klass)) {
- return false; // Already included in the boot image we're compiling against.
- }
- return AotClassLinker::CanReferenceInBootImageExtension(klass, heap);
- }
-
mutable VariableSizedHandleScope hs_;
mutable std::vector<Handle<mirror::Class>> to_insert_;
mutable std::unordered_set<mirror::Object*> marked_objects_;