Prepare for sharing JIT code after fork.
Only encode classes/strings/methods that are in a boot image.
Bug: 119800099
Test: boot
Change-Id: I7ed8ce2ce876ad1c6c1678939cafe4808a67bef4
diff --git a/compiler/optimizing/sharpening.cc b/compiler/optimizing/sharpening.cc
index 3e22edc..03d277f 100644
--- a/compiler/optimizing/sharpening.cc
+++ b/compiler/optimizing/sharpening.cc
@@ -100,6 +100,7 @@
}
code_ptr_location = HInvokeStaticOrDirect::CodePtrLocation::kCallArtMethod;
} else if (Runtime::Current()->UseJitCompilation()) {
+ ScopedObjectAccess soa(Thread::Current());
if (Runtime::Current()->GetJit()->CanEncodeMethod(
callee,
codegen->GetGraph()->IsCompilingForSharedJitCode())) {
diff --git a/runtime/jit/jit.cc b/runtime/jit/jit.cc
index 201f3ce..c92630d 100644
--- a/runtime/jit/jit.cc
+++ b/runtime/jit/jit.cc
@@ -1073,30 +1073,33 @@
thread_pool_->CreateThreads();
}
-bool Jit::CanEncodeMethod(ArtMethod* method ATTRIBUTE_UNUSED,
- bool is_for_shared_region ATTRIBUTE_UNUSED) const {
- // TODO: For shared region, we should only encode a method of a class
- // allocated before any fork.
- return true;
+bool Jit::CanEncodeMethod(ArtMethod* method, bool is_for_shared_region) const {
+ return !is_for_shared_region ||
+ Runtime::Current()->GetHeap()->ObjectIsInBootImageSpace(method->GetDeclaringClass());
}
bool Jit::CanEncodeClass(ObjPtr<mirror::Class> cls, bool is_for_shared_region) const {
- // TODO: For shared region, we should only encode a non-moving class allocated
- // before any fork.
- return !is_for_shared_region || !Runtime::Current()->GetHeap()->IsMovableObject(cls);
+ return !is_for_shared_region || Runtime::Current()->GetHeap()->ObjectIsInBootImageSpace(cls);
}
bool Jit::CanEncodeString(ObjPtr<mirror::String> string, bool is_for_shared_region) const {
- // TODO: For shared region, we should only encode a non-moving string allocated
- // before any fork.
- return !is_for_shared_region || !Runtime::Current()->GetHeap()->IsMovableObject(string);
+ return !is_for_shared_region || Runtime::Current()->GetHeap()->ObjectIsInBootImageSpace(string);
}
-bool Jit::CanAssumeInitialized(ObjPtr<mirror::Class> cls,
- bool is_for_shared_region ATTRIBUTE_UNUSED) const {
- // TODO: For shared region, we should assume initialized if the class is initialized
- // before any fork.
- return cls->IsInitialized();
+bool Jit::CanAssumeInitialized(ObjPtr<mirror::Class> cls, bool is_for_shared_region) const {
+ if (!is_for_shared_region) {
+ return cls->IsInitialized();
+ } else {
+ // Look up the class status in the oat file.
+ const DexFile& dex_file = *cls->GetDexCache()->GetDexFile();
+ const OatDexFile* oat_dex_file = dex_file.GetOatDexFile();
+ // In case we run without an image there won't be a backing oat file.
+ if (oat_dex_file == nullptr || oat_dex_file->GetOatFile() == nullptr) {
+ return false;
+ }
+ uint16_t class_def_index = cls->GetDexClassDefIndex();
+ return oat_dex_file->GetOatClass(class_def_index).GetStatus() >= ClassStatus::kInitialized;
+ }
}
} // namespace jit
diff --git a/runtime/jit/jit.h b/runtime/jit/jit.h
index e44e1c9..d272a18 100644
--- a/runtime/jit/jit.h
+++ b/runtime/jit/jit.h
@@ -326,7 +326,8 @@
// Called by the compiler to know whether it can directly encode the
// method/class/string.
- bool CanEncodeMethod(ArtMethod* method, bool is_for_shared_region) const;
+ bool CanEncodeMethod(ArtMethod* method, bool is_for_shared_region) const
+ REQUIRES_SHARED(Locks::mutator_lock_);
bool CanEncodeClass(ObjPtr<mirror::Class> cls, bool is_for_shared_region) const
REQUIRES_SHARED(Locks::mutator_lock_);
bool CanEncodeString(ObjPtr<mirror::String> string, bool is_for_shared_region) const