ART: Relayout BaseMutex and Mutex
Reduce size of BaseMutex (and thus all derived mutex classes) by changing
the field layout. Reduction from 24B to 16B on 64-bit systems.
Bug: 79365543
Test: m test-art-host
Change-Id: Id7b50aa9af1ae5d249e62573ab67257c12922bfa
diff --git a/runtime/base/mutex.cc b/runtime/base/mutex.cc
index 73b4641..da286d7 100644
--- a/runtime/base/mutex.cc
+++ b/runtime/base/mutex.cc
@@ -195,8 +195,8 @@
};
BaseMutex::BaseMutex(const char* name, LockLevel level)
- : level_(level),
- name_(name),
+ : name_(name),
+ level_(level),
should_respond_to_empty_checkpoint_request_(false) {
if (kLogLockContentions) {
ScopedAllMutexesLock mu(this);
@@ -386,7 +386,7 @@
Mutex::Mutex(const char* name, LockLevel level, bool recursive)
- : BaseMutex(name, level), exclusive_owner_(0), recursive_(recursive), recursion_count_(0) {
+ : BaseMutex(name, level), exclusive_owner_(0), recursion_count_(0), recursive_(recursive) {
#if ART_USE_FUTEXES
DCHECK_EQ(0, state_.load(std::memory_order_relaxed));
DCHECK_EQ(0, num_contenders_.load(std::memory_order_relaxed));
diff --git a/runtime/base/mutex.h b/runtime/base/mutex.h
index 1cf4ddd..602d183 100644
--- a/runtime/base/mutex.h
+++ b/runtime/base/mutex.h
@@ -57,7 +57,7 @@
// partial ordering and thereby cause deadlock situations to fail checks.
//
// [1] http://www.drdobbs.com/parallel/use-lock-hierarchies-to-avoid-deadlock/204801163
-enum LockLevel {
+enum LockLevel : uint8_t {
kLoggingLock = 0,
kSwapMutexesLock,
kUnexpectedSignalLock,
@@ -142,20 +142,20 @@
};
std::ostream& operator<<(std::ostream& os, const LockLevel& rhs);
-const bool kDebugLocking = kIsDebugBuild;
+constexpr bool kDebugLocking = kIsDebugBuild;
// Record Log contention information, dumpable via SIGQUIT.
#ifdef ART_USE_FUTEXES
// To enable lock contention logging, set this to true.
-const bool kLogLockContentions = false;
+constexpr bool kLogLockContentions = false;
#else
// Keep this false as lock contention logging is supported only with
// futex.
-const bool kLogLockContentions = false;
+constexpr bool kLogLockContentions = false;
#endif
-const size_t kContentionLogSize = 4;
-const size_t kContentionLogDataSize = kLogLockContentions ? 1 : 0;
-const size_t kAllMutexDataSize = kLogLockContentions ? 1 : 0;
+constexpr size_t kContentionLogSize = 4;
+constexpr size_t kContentionLogDataSize = kLogLockContentions ? 1 : 0;
+constexpr size_t kAllMutexDataSize = kLogLockContentions ? 1 : 0;
// Base class for all Mutex implementations
class BaseMutex {
@@ -196,9 +196,7 @@
void RecordContention(uint64_t blocked_tid, uint64_t owner_tid, uint64_t nano_time_blocked);
void DumpContention(std::ostream& os) const;
- const LockLevel level_; // Support for lock hierarchy.
const char* const name_;
- bool should_respond_to_empty_checkpoint_request_;
// A log entry that records contention but makes no guarantee that either tid will be held live.
struct ContentionLogEntry {
@@ -221,6 +219,9 @@
};
ContentionLogData contention_log_data_[kContentionLogDataSize];
+ const LockLevel level_; // Support for lock hierarchy.
+ bool should_respond_to_empty_checkpoint_request_;
+
public:
bool HasEverContended() const {
if (kLogLockContentions) {
@@ -307,8 +308,10 @@
pthread_mutex_t mutex_;
Atomic<pid_t> exclusive_owner_; // Guarded by mutex_. Asynchronous reads are OK.
#endif
- const bool recursive_; // Can the lock be recursively held?
+
unsigned int recursion_count_;
+ const bool recursive_; // Can the lock be recursively held?
+
friend class ConditionVariable;
DISALLOW_COPY_AND_ASSIGN(Mutex);
};