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);
 };