Merge "runtime: Properly unload partially loaded image spaces" into oc-dev
diff --git a/runtime/gc/space/image_space.cc b/runtime/gc/space/image_space.cc
index e9f0758..0f51b87 100644
--- a/runtime/gc/space/image_space.cc
+++ b/runtime/gc/space/image_space.cc
@@ -1695,6 +1695,29 @@
return true;
}
+ImageSpace::~ImageSpace() {
+ Runtime* runtime = Runtime::Current();
+ if (runtime == nullptr) {
+ return;
+ }
+
+ if (GetImageHeader().IsAppImage()) {
+ // This image space did not modify resolution method then in Init.
+ return;
+ }
+
+ if (!runtime->HasResolutionMethod()) {
+ // Another image space has already unloaded the below methods.
+ return;
+ }
+
+ runtime->ClearInstructionSet();
+ runtime->ClearResolutionMethod();
+ runtime->ClearImtConflictMethod();
+ runtime->ClearImtUnimplementedMethod();
+ runtime->ClearCalleeSaveMethods();
+}
+
std::unique_ptr<ImageSpace> ImageSpace::CreateFromAppImage(const char* image,
const OatFile* oat_file,
std::string* error_msg) {
diff --git a/runtime/gc/space/image_space.h b/runtime/gc/space/image_space.h
index 199bbdd..aa3dd42 100644
--- a/runtime/gc/space/image_space.h
+++ b/runtime/gc/space/image_space.h
@@ -159,6 +159,9 @@
void DumpSections(std::ostream& os) const;
+ // De-initialize the image-space by undoing the effects in Init().
+ virtual ~ImageSpace();
+
protected:
// Tries to initialize an ImageSpace from the given image path, returning null on error.
//
diff --git a/runtime/runtime.cc b/runtime/runtime.cc
index 7afbe72..229d80b 100644
--- a/runtime/runtime.cc
+++ b/runtime/runtime.cc
@@ -1962,12 +1962,23 @@
}
}
+void Runtime::ClearInstructionSet() {
+ instruction_set_ = InstructionSet::kNone;
+}
+
void Runtime::SetCalleeSaveMethod(ArtMethod* method, CalleeSaveType type) {
DCHECK_LT(static_cast<int>(type), static_cast<int>(kLastCalleeSaveType));
CHECK(method != nullptr);
callee_save_methods_[type] = reinterpret_cast<uintptr_t>(method);
}
+void Runtime::ClearCalleeSaveMethods() {
+ for (size_t i = 0; i < static_cast<size_t>(kLastCalleeSaveType); ++i) {
+ CalleeSaveType type = static_cast<CalleeSaveType>(i);
+ callee_save_methods_[type] = reinterpret_cast<uintptr_t>(nullptr);
+ }
+}
+
void Runtime::RegisterAppInfo(const std::vector<std::string>& code_paths,
const std::string& profile_output_filename) {
if (jit_.get() == nullptr) {
diff --git a/runtime/runtime.h b/runtime/runtime.h
index b91cb0c..3a328dd 100644
--- a/runtime/runtime.h
+++ b/runtime/runtime.h
@@ -356,6 +356,9 @@
}
void SetResolutionMethod(ArtMethod* method) REQUIRES_SHARED(Locks::mutator_lock_);
+ void ClearResolutionMethod() {
+ resolution_method_ = nullptr;
+ }
ArtMethod* CreateResolutionMethod() REQUIRES_SHARED(Locks::mutator_lock_);
@@ -367,6 +370,10 @@
return imt_conflict_method_ != nullptr;
}
+ void ClearImtConflictMethod() {
+ imt_conflict_method_ = nullptr;
+ }
+
void FixupConflictTables();
void SetImtConflictMethod(ArtMethod* method) REQUIRES_SHARED(Locks::mutator_lock_);
void SetImtUnimplementedMethod(ArtMethod* method) REQUIRES_SHARED(Locks::mutator_lock_);
@@ -374,6 +381,10 @@
ArtMethod* CreateImtConflictMethod(LinearAlloc* linear_alloc)
REQUIRES_SHARED(Locks::mutator_lock_);
+ void ClearImtUnimplementedMethod() {
+ imt_unimplemented_method_ = nullptr;
+ }
+
// Returns a special method that describes all callee saves being spilled to the stack.
enum CalleeSaveType {
kSaveAllCalleeSaves, // All callee-save registers.
@@ -409,8 +420,10 @@
}
void SetInstructionSet(InstructionSet instruction_set);
+ void ClearInstructionSet();
void SetCalleeSaveMethod(ArtMethod* method, CalleeSaveType type);
+ void ClearCalleeSaveMethods();
ArtMethod* CreateCalleeSaveMethod() REQUIRES_SHARED(Locks::mutator_lock_);