Continue try allocating until we've reached max capacity.
004-StackWalk currently fails because we start with a too low code cache
to allocate code for a method the test expects to be JITted. To de-flake
the test, just keep on trying to allocate.
Test: test.py
Change-Id: Ie33e13bcc8825058259e12b0d4d552e89c9816e3
diff --git a/runtime/jit/jit_code_cache.cc b/runtime/jit/jit_code_cache.cc
index 29951a7..cf07fe5 100644
--- a/runtime/jit/jit_code_cache.cc
+++ b/runtime/jit/jit_code_cache.cc
@@ -965,8 +965,8 @@
const uint8_t* code;
const uint8_t* data;
- // We might need to try the allocation twice (with GC in between to free up memory).
- for (int i = 0; i < 2; i++) {
+ while (true) {
+ bool at_max_capacity = false;
{
ScopedThreadSuspension sts(self, kSuspended);
MutexLock mu(self, *Locks::jit_lock_);
@@ -974,18 +974,23 @@
ScopedCodeCacheWrite ccw(*region);
code = region->AllocateCode(code_size);
data = region->AllocateData(data_size);
+ at_max_capacity = IsAtMaxCapacity();
}
- if (code == nullptr || data == nullptr) {
- Free(self, region, code, data);
- if (i == 0) {
- GarbageCollectCache(self);
- continue; // Retry after GC.
- } else {
- return false; // Fail.
- }
+ if (code != nullptr && data != nullptr) {
+ break;
}
- break; // Success.
+ Free(self, region, code, data);
+ if (at_max_capacity) {
+ VLOG(jit) << "JIT failed to allocate code of size "
+ << PrettySize(code_size)
+ << ", and data of size "
+ << PrettySize(data_size);
+ return false;
+ }
+ // Run a code cache collection and try again.
+ GarbageCollectCache(self);
}
+
*reserved_code = ArrayRef<const uint8_t>(code, code_size);
*reserved_data = ArrayRef<const uint8_t>(data, data_size);
@@ -1095,8 +1100,12 @@
}
}
+bool JitCodeCache::IsAtMaxCapacity() const {
+ return private_region_.GetCurrentCapacity() == private_region_.GetMaxCapacity();
+}
+
bool JitCodeCache::ShouldDoFullCollection() {
- if (private_region_.GetCurrentCapacity() == private_region_.GetMaxCapacity()) {
+ if (IsAtMaxCapacity()) {
// Always do a full collection when the code cache is full.
return true;
} else if (private_region_.GetCurrentCapacity() < kReservedCapacity) {
diff --git a/runtime/jit/jit_code_cache.h b/runtime/jit/jit_code_cache.h
index 50e1e2b..cefbf25 100644
--- a/runtime/jit/jit_code_cache.h
+++ b/runtime/jit/jit_code_cache.h
@@ -466,6 +466,9 @@
// Notify all waiting threads that a collection is done.
void NotifyCollectionDone(Thread* self) REQUIRES(Locks::jit_lock_);
+ // Return whether the code cache's capacity is at its maximum.
+ bool IsAtMaxCapacity() const REQUIRES(Locks::jit_lock_);
+
// Return whether we should do a full collection given the current state of the cache.
bool ShouldDoFullCollection()
REQUIRES(Locks::jit_lock_)