Supersede the Lock union type with a word-sized integer in the object
instance header.  An object's lock member is now just a bit-field.
diff --git a/vm/Sync.c b/vm/Sync.c
index 5505166..f254324 100644
--- a/vm/Sync.c
+++ b/vm/Sync.c
@@ -285,7 +285,7 @@
      * latch it so that it doesn't change out from under
      * us if we get preempted.
      */
-    thin = obj->lock.thin;
+    thin = obj->lock;
     if (LW_SHAPE(thin) == LW_SHAPE_FAT) {
         return thread == LW_MONITOR(thin)->owner;
     } else {
@@ -297,7 +297,7 @@
  * Free the monitor associated with an object and make the object's lock
  * thin again.  This is called during garbage collection.
  */
-void dvmFreeObjectMonitor_internal(Lock *lock)
+void dvmFreeObjectMonitor_internal(u4 *lock)
 {
     Monitor *mon;
 
@@ -307,11 +307,11 @@
 
 #ifdef WITH_DEADLOCK_PREDICTION
     if (gDvm.deadlockPredictMode != kDPOff)
-        removeCollectedObject(LW_MONITOR(lock->thin)->obj);
+        removeCollectedObject(LW_MONITOR(*lock)->obj);
 #endif
 
-    mon = LW_MONITOR(lock->thin);
-    lock->thin = DVM_LOCK_INITIAL_THIN_VALUE;
+    mon = LW_MONITOR(*lock);
+    *lock = DVM_LOCK_INITIAL_THIN_VALUE;
 
     /* This lock is associated with an object
      * that's being swept.  The only possible way
@@ -748,7 +748,8 @@
  */
 void dvmLockObject(Thread* self, Object *obj)
 {
-    volatile u4 *thinp = &obj->lock.thin;
+    volatile u4 *thinp = &obj->lock;
+    u4 hashState;
     u4 thin;
     u4 threadId = self->threadId;
     Monitor *mon;
@@ -757,7 +758,7 @@
      * this is the common case and will usually succeed.
      */
     thin = threadId << LW_LOCK_OWNER_SHIFT;
-    thin |= *thinp & (LW_HASH_STATE_MASK << LW_HASH_STATE_SHIFT);
+    thin |= LW_HASH_STATE(*thinp) << LW_HASH_STATE_SHIFT;
     if (!ATOMIC_CMP_SWAP((int32_t *)thinp,
                          (int32_t)DVM_LOCK_INITIAL_THIN_VALUE,
                          (int32_t)thin)) {
@@ -819,7 +820,7 @@
                         }
                     }
                     thin = threadId << LW_LOCK_OWNER_SHIFT;
-                    thin |= *thinp & (LW_HASH_STATE_MASK << LW_HASH_STATE_SHIFT);
+                    thin |= LW_HASH_STATE(*thinp) << LW_HASH_STATE_SHIFT;
                 } while (!ATOMIC_CMP_SWAP((int32_t *)thinp,
                                           (int32_t)DVM_LOCK_INITIAL_THIN_VALUE,
                                           (int32_t)thin));
@@ -838,7 +839,8 @@
                  * to avoid "re-locking" it in fat_lock.
                  */
                 mon = dvmCreateMonitor(obj);
-                obj->lock.thin = (u4)mon | LW_SHAPE_FAT;
+                hashState = LW_HASH_STATE(*thinp) << LW_HASH_STATE_SHIFT;
+                obj->lock = (u4)mon | hashState | LW_SHAPE_FAT;
                 LOG_THIN("(%d) lock 0x%08x fattened\n",
                          threadId, (uint)&obj->lock);
 
@@ -847,11 +849,11 @@
             }
 
             /* The lock is already fat, which means
-             * that obj->lock.mon is a regular (Monitor *).
+             * that obj->lock is a regular (Monitor *).
              */
         fat_lock:
-            assert(LW_MONITOR(obj->lock.thin) != NULL);
-            lockMonitor(self, LW_MONITOR(obj->lock.thin));
+            assert(LW_MONITOR(obj->lock) != NULL);
+            lockMonitor(self, LW_MONITOR(obj->lock));
         }
     }
     // else, the lock was acquired with the ATOMIC_CMP_SWAP().
@@ -915,7 +917,7 @@
  */
 bool dvmUnlockObject(Thread* self, Object *obj)
 {
-    volatile u4 *thinp = &obj->lock.thin;
+    volatile u4 *thinp = &obj->lock;
     u4 threadId = self->threadId;
     u4 thin;
 
@@ -949,8 +951,8 @@
     } else {
         /* It's a fat lock.
          */
-        assert(LW_MONITOR(obj->lock.thin) != NULL);
-        if (!unlockMonitor(self, LW_MONITOR(obj->lock.thin))) {
+        assert(LW_MONITOR(obj->lock) != NULL);
+        if (!unlockMonitor(self, LW_MONITOR(obj->lock))) {
             /* exception has been raised */
             return false;
         }
@@ -972,8 +974,9 @@
 void dvmObjectWait(Thread* self, Object *obj, s8 msec, s4 nsec,
     bool interruptShouldThrow)
 {
-    Monitor* mon = LW_MONITOR(obj->lock.thin);
-    u4 thin = obj->lock.thin;
+    Monitor* mon = LW_MONITOR(obj->lock);
+    u4 hashState;
+    u4 thin = obj->lock;
 
     /* If the lock is still thin, we need to fatten it.
      */
@@ -1005,7 +1008,8 @@
         /* Make the monitor public now that it's in the right state.
          */
         MEM_BARRIER();
-        obj->lock.thin = (u4)mon | LW_SHAPE_FAT;
+        hashState = LW_HASH_STATE(thin) << LW_HASH_STATE_SHIFT;
+        obj->lock = (u4)mon | hashState | LW_SHAPE_FAT;
     }
 
     waitMonitor(self, mon, msec, nsec, interruptShouldThrow);
@@ -1016,7 +1020,7 @@
  */
 void dvmObjectNotify(Thread* self, Object *obj)
 {
-    u4 thin = obj->lock.thin;
+    u4 thin = obj->lock;
 
     /* If the lock is still thin, there aren't any waiters;
      * waiting on an object forces lock fattening.
@@ -1044,7 +1048,7 @@
  */
 void dvmObjectNotifyAll(Thread* self, Object *obj)
 {
-    u4 thin = obj->lock.thin;
+    u4 thin = obj->lock;
 
     /* If the lock is still thin, there aren't any waiters;
      * waiting on an object forces lock fattening.
@@ -1413,13 +1417,13 @@
  */
 static bool objectInChildList(const Object* parent, Object* child)
 {
-    Lock lock = parent->lock;
+    u4 lock = parent->lock;
     if (!IS_LOCK_FAT(&lock)) {
         //LOGI("on thin\n");
         return false;
     }
 
-    return expandObjHas(&lock.mon->historyChildren, child);
+    return expandObjHas(&LW_MONITOR(lock)->historyChildren, child);
 }
 
 /*
@@ -1427,7 +1431,7 @@
  */
 static void dumpKids(Object* parent)
 {
-    Monitor* mon = parent->lock.mon;
+    Monitor* mon = LW_MONITOR(parent->lock);
 
     printf("Children of %p:", parent);
     expandObjDump(&mon->historyChildren);
@@ -1440,17 +1444,17 @@
  */
 static void linkParentToChild(Object* parent, Object* child)
 {
-    //assert(parent->lock.mon->owner == dvmThreadSelf());   // !owned for merge
+    //assert(LW_MONITOR(parent->lock)->owner == dvmThreadSelf());   // !owned for merge
     assert(IS_LOCK_FAT(&parent->lock));
     assert(IS_LOCK_FAT(&child->lock));
     assert(parent != child);
     Monitor* mon;
 
-    mon = parent->lock.mon;
+    mon = LW_MONITOR(parent->lock);
     assert(!expandObjHas(&mon->historyChildren, child));
     expandObjAddEntry(&mon->historyChildren, child);
 
-    mon = child->lock.mon;
+    mon = LW_MONITOR(child->lock);
     assert(!expandObjHas(&mon->historyParents, parent));
     expandObjAddEntry(&mon->historyParents, parent);
 }
@@ -1461,20 +1465,20 @@
  */
 static void unlinkParentFromChild(Object* parent, Object* child)
 {
-    //assert(parent->lock.mon->owner == dvmThreadSelf());   // !owned for GC
+    //assert(LW_MONITOR(parent->lock)->owner == dvmThreadSelf());   // !owned for GC
     assert(IS_LOCK_FAT(&parent->lock));
     assert(IS_LOCK_FAT(&child->lock));
     assert(parent != child);
     Monitor* mon;
 
-    mon = parent->lock.mon;
+    mon = LW_MONITOR(parent->lock);
     if (!expandObjRemoveEntry(&mon->historyChildren, child)) {
         LOGW("WARNING: child %p not found in parent %p\n", child, parent);
     }
     assert(!expandObjHas(&mon->historyChildren, child));
     assert(expandObjCheckForDuplicates(&mon->historyChildren) < 0);
 
-    mon = child->lock.mon;
+    mon = LW_MONITOR(child->lock);
     if (!expandObjRemoveEntry(&mon->historyParents, parent)) {
         LOGW("WARNING: parent %p not found in child %p\n", parent, child);
     }
@@ -1517,7 +1521,7 @@
 static bool traverseTree(Thread* self, const Object* obj)
 {
     assert(IS_LOCK_FAT(&obj->lock));
-    Monitor* mon = obj->lock.mon;
+    Monitor* mon = LW_MONITOR(obj->lock);
 
     /*
      * Have we been here before?
@@ -1561,7 +1565,7 @@
     int i;
     for (i = expandBufGetCount(pList)-1; i >= 0; i--) {
         const Object* child = expandBufGetEntry(pList, i);
-        Lock lock = child->lock;
+        u4 lock = child->lock;
         if (!IS_LOCK_FAT(&lock))
             continue;
         if (!traverseTree(self, child)) {
@@ -1621,13 +1625,14 @@
             acqObj, LW_LOCK_COUNT(acqObj->lock.thin));
         Monitor* newMon = dvmCreateMonitor(acqObj);
         lockMonitor(self, newMon);      // can't stall, don't need VMWAIT
-        newMon->lockCount += LW_LOCK_COUNT(acqObj->lock.thin);
-        acqObj->lock.mon = newMon;
+        newMon->lockCount += LW_LOCK_COUNT(acqObj->lock);
+        u4 hashState = LW_HASH_STATE(acqObj->lock) << LW_HASH_STATE_SHIFT;
+        acqObj->lock = (u4)newMon | hashState | LW_SHAPE_FAT;
     }
 
     /* if we don't have a stack trace for this monitor, establish one */
-    if (acqObj->lock.mon->historyRawStackTrace == NULL) {
-        Monitor* mon = acqObj->lock.mon;
+    if (LW_MONITOR(acqObj->lock)->historyRawStackTrace == NULL) {
+        Monitor* mon = LW_MONITOR(acqObj->lock);
         mon->historyRawStackTrace = dvmFillInStackTraceRaw(self,
             &mon->historyStackDepth);
     }
@@ -1665,11 +1670,12 @@
      */
     if (!IS_LOCK_FAT(&mrl->obj->lock)) {
         LOGVV("fattening parent %p f/b/o child %p (recur=%d)\n",
-            mrl->obj, acqObj, LW_LOCK_COUNT(mrl->obj->lock.thin));
+            mrl->obj, acqObj, LW_LOCK_COUNT(mrl->obj->lock));
         Monitor* newMon = dvmCreateMonitor(mrl->obj);
         lockMonitor(self, newMon);      // can't stall, don't need VMWAIT
-        newMon->lockCount += LW_LOCK_COUNT(mrl->obj->lock.thin);
-        mrl->obj->lock.mon = newMon;
+        newMon->lockCount += LW_LOCK_COUNT(mrl->obj->lock);
+        u4 hashState = LW_HASH_STATE(mrl->obj->lock) << LW_HASH_STATE_SHIFT;
+        mrl->obj->lock = (u4)newMon | hashState | LW_SHAPE_FAT;
     }
 
     /*
@@ -1732,7 +1738,7 @@
     int i;
 
     assert(IS_LOCK_FAT(&child->lock));
-    mon = child->lock.mon;
+    mon = LW_MONITOR(child->lock);
     ExpandingObjectList* pList = &mon->historyChildren;
 
     for (i = expandBufGetCount(pList)-1; i >= 0; i--) {
@@ -1791,11 +1797,11 @@
     int i;
 
     assert(IS_LOCK_FAT(&obj->lock));
-    mon = obj->lock.mon;
+    mon = LW_MONITOR(obj->lock);
     pList = &mon->historyParents;
     for (i = expandBufGetCount(pList)-1; i >= 0; i--) {
         Object* parent = expandBufGetEntry(pList, i);
-        Monitor* parentMon = parent->lock.mon;
+        Monitor* parentMon = LW_MONITOR(parent->lock);
 
         if (!expandObjRemoveEntry(&parentMon->historyChildren, obj)) {
             LOGW("WARNING: child %p not found in parent %p\n", obj, parent);
@@ -1812,7 +1818,7 @@
     pList = &mon->historyChildren;
     for (i = expandBufGetCount(pList)-1; i >= 0; i--) {
         Object* child = expandBufGetEntry(pList, i);
-        Monitor* childMon = child->lock.mon;
+        Monitor* childMon = LW_MONITOR(child->lock);
 
         if (!expandObjRemoveEntry(&childMon->historyParents, obj)) {
             LOGW("WARNING: parent %p not found in child %p\n", obj, child);
diff --git a/vm/Sync.h b/vm/Sync.h
index c3785b3..7f5ef08 100644
--- a/vm/Sync.h
+++ b/vm/Sync.h
@@ -50,30 +50,18 @@
 #define QUIET_ZYGOTE_MONITOR 1
 
 /*
- * Synchronization lock, included in every object.
- *
- * We want this to be a 32-bit "thin lock", holding the lock level and
- * the owner's threadId, that inflates to a Monitor pointer when there
- * is contention or somebody waits on it.
- */
-typedef union Lock {
-    u4          thin;
-    Monitor*    mon;
-} Lock;
-
-/*
  * Initialize a Lock to the proper starting value.
  * This is necessary for thin locking.
  */
 #define DVM_LOCK_INITIAL_THIN_VALUE (0)
 
 #define DVM_LOCK_INIT(lock) \
-    do { (lock)->thin = DVM_LOCK_INITIAL_THIN_VALUE; } while (0)
+    do { *(lock) = DVM_LOCK_INITIAL_THIN_VALUE; } while (0)
 
 /*
  * Returns true if the lock has been fattened.
  */
-#define IS_LOCK_FAT(lock)   (LW_SHAPE((lock)->thin) == LW_SHAPE_FAT)
+#define IS_LOCK_FAT(lock)   (LW_SHAPE(*(lock)) == LW_SHAPE_FAT)
 
 /*
  * Acquire the object's monitor.
@@ -114,7 +102,7 @@
 Monitor* dvmCreateMonitor(struct Object* obj);
 
 /* free an object's monitor during GC */
-void dvmFreeObjectMonitor_internal(Lock* lock);
+void dvmFreeObjectMonitor_internal(u4 *lock);
 #define dvmFreeObjectMonitor(obj) \
     do { \
         Object *DFM_obj_ = (obj); \
diff --git a/vm/oo/Object.h b/vm/oo/Object.h
index ba2d9bb..df167d5 100644
--- a/vm/oo/Object.h
+++ b/vm/oo/Object.h
@@ -243,8 +243,11 @@
     /* ptr to class object */
     ClassObject*    clazz;
 
-    /* thin lock or "fat" monitor */
-    Lock            lock;
+    /*
+     * A word containing either a "thin" lock or a "fat" monitor.  See
+     * the comments in Sync.c for a description of its layout.
+     */
+    u4              lock;
 } Object;
 
 /*