diff options
| -rw-r--r-- | runtime/indirect_reference_table.cc | 15 | ||||
| -rw-r--r-- | runtime/indirect_reference_table.h | 1 | ||||
| -rw-r--r-- | runtime/jni/jni_internal.cc | 20 |
3 files changed, 19 insertions, 17 deletions
diff --git a/runtime/indirect_reference_table.cc b/runtime/indirect_reference_table.cc index fbe678bea2..ebf382f2ec 100644 --- a/runtime/indirect_reference_table.cc +++ b/runtime/indirect_reference_table.cc @@ -561,8 +561,14 @@ void IndirectReferenceTable::SetSegmentState(IRTSegmentState new_state) { } bool IndirectReferenceTable::EnsureFreeCapacity(size_t free_capacity, std::string* error_msg) { + DCHECK_GE(free_capacity, static_cast<size_t>(1)); + if (free_capacity > kMaxTableSizeInBytes) { + // Arithmetic might even overflow. + *error_msg = "Requested table size implausibly large"; + return false; + } size_t top_index = segment_state_.top_index; - if (top_index < max_entries_ && top_index + free_capacity <= max_entries_) { + if (top_index + free_capacity <= max_entries_) { return true; } @@ -573,13 +579,6 @@ bool IndirectReferenceTable::EnsureFreeCapacity(size_t free_capacity, std::strin } // Try to increase the table size. - - // Would this overflow? - if (std::numeric_limits<size_t>::max() - free_capacity < top_index) { - *error_msg = "Cannot resize table, overflow."; - return false; - } - if (!Resize(top_index + free_capacity, error_msg)) { LOG(WARNING) << "JNI ERROR: Unable to reserve space in EnsureFreeCapacity (" << free_capacity << "): " << std::endl diff --git a/runtime/indirect_reference_table.h b/runtime/indirect_reference_table.h index 084b534a70..e279422b4b 100644 --- a/runtime/indirect_reference_table.h +++ b/runtime/indirect_reference_table.h @@ -336,6 +336,7 @@ class IndirectReferenceTable { } // Ensure that at least free_capacity elements are available, or return false. + // Caller ensures free_capacity > 0. bool EnsureFreeCapacity(size_t free_capacity, std::string* error_msg) REQUIRES_SHARED(Locks::mutator_lock_); // See implementation of EnsureFreeCapacity. We'll only state here how much is trivially free, diff --git a/runtime/jni/jni_internal.cc b/runtime/jni/jni_internal.cc index 7a25b4b5c5..e3153fdace 100644 --- a/runtime/jni/jni_internal.cc +++ b/runtime/jni/jni_internal.cc @@ -2847,17 +2847,19 @@ class JNI { static jint EnsureLocalCapacityInternal(ScopedObjectAccess& soa, jint desired_capacity, const char* caller) REQUIRES_SHARED(Locks::mutator_lock_) { - if (desired_capacity < 0) { + if (desired_capacity > 0) { + std::string error_msg; + if (!soa.Env()->locals_.EnsureFreeCapacity(static_cast<size_t>(desired_capacity), + &error_msg)) { + std::string caller_error = android::base::StringPrintf("%s: %s", caller, + error_msg.c_str()); + soa.Self()->ThrowOutOfMemoryError(caller_error.c_str()); + return JNI_ERR; + } + } else if (desired_capacity < 0) { LOG(ERROR) << "Invalid capacity given to " << caller << ": " << desired_capacity; return JNI_ERR; - } - - std::string error_msg; - if (!soa.Env()->locals_.EnsureFreeCapacity(static_cast<size_t>(desired_capacity), &error_msg)) { - std::string caller_error = android::base::StringPrintf("%s: %s", caller, error_msg.c_str()); - soa.Self()->ThrowOutOfMemoryError(caller_error.c_str()); - return JNI_ERR; - } + } // The zero case is a no-op. return JNI_OK; } |