Merge "Fix pending exception failure for encoded statics" into nyc-mr1-dev
diff --git a/runtime/gc/collector_type.h b/runtime/gc/collector_type.h
index a06ccbe..f14d086 100644
--- a/runtime/gc/collector_type.h
+++ b/runtime/gc/collector_type.h
@@ -49,6 +49,8 @@
kCollectorTypeHomogeneousSpaceCompact,
// Class linker fake collector.
kCollectorTypeClassLinker,
+ // JIT Code cache fake collector.
+ kCollectorTypeJitCodeCache,
};
std::ostream& operator<<(std::ostream& os, const CollectorType& collector_type);
diff --git a/runtime/gc/gc_cause.cc b/runtime/gc/gc_cause.cc
index 1b03460..cf765f5 100644
--- a/runtime/gc/gc_cause.cc
+++ b/runtime/gc/gc_cause.cc
@@ -36,6 +36,7 @@
case kGcCauseInstrumentation: return "Instrumentation";
case kGcCauseAddRemoveAppImageSpace: return "AddRemoveAppImageSpace";
case kGcCauseClassLinker: return "ClassLinker";
+ case kGcCauseJitCodeCache: return "JitCodeCache";
default:
LOG(FATAL) << "Unreachable";
UNREACHABLE();
diff --git a/runtime/gc/gc_cause.h b/runtime/gc/gc_cause.h
index df3aba9..7d2cc4f 100644
--- a/runtime/gc/gc_cause.h
+++ b/runtime/gc/gc_cause.h
@@ -47,6 +47,8 @@
kGcCauseHomogeneousSpaceCompact,
// Class linker cause, used to guard filling art methods with special values.
kGcCauseClassLinker,
+ // Not a real GC cause, used to implement exclusion between code cache metadata and GC.
+ kGcCauseJitCodeCache,
};
const char* PrettyCause(GcCause cause);
diff --git a/runtime/gc/heap.cc b/runtime/gc/heap.cc
index cdd5f2e..03b7713 100644
--- a/runtime/gc/heap.cc
+++ b/runtime/gc/heap.cc
@@ -2709,7 +2709,8 @@
}
// It's time to clear all inline caches, in case some classes can be unloaded.
- if ((gc_type == collector::kGcTypeFull) && (runtime->GetJit() != nullptr)) {
+ if (((gc_type == collector::kGcTypeFull) || (gc_type == collector::kGcTypePartial)) &&
+ (runtime->GetJit() != nullptr)) {
runtime->GetJit()->GetCodeCache()->ClearGcRootsInInlineCaches(self);
}
diff --git a/runtime/gc/space/image_space.cc b/runtime/gc/space/image_space.cc
index 5a52e9a..b7b9ffe 100644
--- a/runtime/gc/space/image_space.cc
+++ b/runtime/gc/space/image_space.cc
@@ -505,6 +505,17 @@
error_msg);
}
if (space != nullptr) {
+ // Check whether there is enough space left over in the data partition. Even if we can load
+ // the image, we need to be conservative, as some parts of the platform are not very tolerant
+ // of space constraints.
+ // ImageSpace doesn't know about the data partition per se, it relies on the FindImageFilename
+ // helper (which relies on GetDalvikCache). So for now, if we load an image out of /system,
+ // ignore the check (as it would test for free space in /system instead).
+ if (!is_system && !CheckSpace(*image_filename, error_msg)) {
+ // No. Delete the generated image and try to run out of the dex files.
+ PruneDalvikCache(image_isa);
+ return nullptr;
+ }
return space;
}
diff --git a/runtime/gc/space/image_space_fs.h b/runtime/gc/space/image_space_fs.h
index 57bf59f..fc9a3cf 100644
--- a/runtime/gc/space/image_space_fs.h
+++ b/runtime/gc/space/image_space_fs.h
@@ -114,8 +114,21 @@
file.reset(OS::CreateEmptyFile(file_name));
if (file.get() == nullptr) {
+ int saved_errno = errno;
PLOG(WARNING) << "Failed to create boot marker.";
- return;
+ if (saved_errno != ENOSPC) {
+ return;
+ }
+
+ LOG(WARNING) << "Pruning dalvik cache because of low-memory situation.";
+ impl::DeleteDirectoryContents(isa_subdir, false);
+
+ // Try once more.
+ file.reset(OS::OpenFileReadWrite(file_name));
+ if (file == nullptr) {
+ PLOG(WARNING) << "Failed to create boot marker.";
+ return;
+ }
}
} else {
if (!file->ReadFully(&num_failed_boots, sizeof(num_failed_boots))) {
diff --git a/runtime/jit/jit_code_cache.cc b/runtime/jit/jit_code_cache.cc
index 6b6f5a5..8c1d776 100644
--- a/runtime/jit/jit_code_cache.cc
+++ b/runtime/jit/jit_code_cache.cc
@@ -25,6 +25,7 @@
#include "debugger_interface.h"
#include "entrypoints/runtime_asm_entrypoints.h"
#include "gc/accounting/bitmap-inl.h"
+#include "gc/scoped_gc_critical_section.h"
#include "jit/jit.h"
#include "jit/profiling_info.h"
#include "linear_alloc.h"
@@ -727,6 +728,9 @@
RemoveUnmarkedCode(self);
if (collect_profiling_info) {
+ ScopedThreadSuspension sts(self, kSuspended);
+ gc::ScopedGCCriticalSection gcs(
+ self, gc::kGcCauseJitCodeCache, gc::kCollectorTypeJitCodeCache);
MutexLock mu(self, lock_);
// Free all profiling infos of methods not compiled nor being compiled.
auto profiling_kept_end = std::remove_if(profiling_infos_.begin(), profiling_infos_.end(),
diff --git a/runtime/jit/jit_code_cache.h b/runtime/jit/jit_code_cache.h
index 4df6762..6dc1578 100644
--- a/runtime/jit/jit_code_cache.h
+++ b/runtime/jit/jit_code_cache.h
@@ -255,8 +255,7 @@
SHARED_REQUIRES(Locks::mutator_lock_);
bool CheckLiveCompiledCodeHasProfilingInfo()
- REQUIRES(lock_)
- SHARED_REQUIRES(Locks::mutator_lock_);
+ REQUIRES(lock_);
void FreeCode(uint8_t* code) REQUIRES(lock_);
uint8_t* AllocateCode(size_t code_size) REQUIRES(lock_);