Merge change I88786692

* changes:
  Fix leaks in ICU JNI.
diff --git a/libcore/math/src/main/java/java/math/BigDecimal.java b/libcore/math/src/main/java/java/math/BigDecimal.java
index 6c00560..33042ba 100644
--- a/libcore/math/src/main/java/java/math/BigDecimal.java
+++ b/libcore/math/src/main/java/java/math/BigDecimal.java
@@ -2148,7 +2148,7 @@
         long newScale = scale;
 
         if (isZero()) {
-            return new BigDecimal("0");
+            return this;
         }
         BigInteger strippedBI = getUnscaledValue();
         BigInteger[] quotAndRem;
diff --git a/libcore/tools/runner/expectations.txt b/libcore/tools/runner/expectations.txt
index 641ec88..9644ef7 100644
--- a/libcore/tools/runner/expectations.txt
+++ b/libcore/tools/runner/expectations.txt
@@ -674,3 +674,25 @@
 test sun.security.smartcardio
 result UNSUPPORTED
 
+# Our exception messages don't match the RIs
+test java.lang.StringBuilder.Exceptions
+result EXEC_FAILED
+pattern .*got java\.lang\.StringIndexOutOfBoundsException: null - FAILED.*
+
+test java.lang.StringBuffer.Exceptions
+result EXEC_FAILED
+pattern .*got java\.lang\.StringIndexOutOfBoundsException: null - FAILED.*
+
+
+# We don't expose Java 6 APIs
+test java.lang.String.IsEmpty
+result COMPILE_FAILED
+pattern .*cannot find symbol.*method isEmpty\(\).*
+
+test java.lang.String.Exceptions
+result COMPILE_FAILED
+pattern .*cannot find symbol.*new String.*
+
+test java.lang.String.Encodings
+result COMPILE_FAILED
+pattern .*cannot find symbol.*new String.*
diff --git a/vm/Sync.c b/vm/Sync.c
index 8528c0f..5f9c2fa 100644
--- a/vm/Sync.c
+++ b/vm/Sync.c
@@ -93,9 +93,10 @@
  * (ACM 1998).  Things are even easier for us, though, because we have
  * a full 32 bits to work with.
  *
- * The two states that an Object's lock may have are referred to as
- * "thin" and "fat".  The lock may transition between the two states
- * for various reasons.
+ * The two states of an Object's lock are referred to as "thin" and
+ * "fat".  A lock may transition from the "thin" state to the "fat"
+ * state and this transition is referred to as inflation.  Once a lock
+ * has been inflated it remains in the "fat" state indefinitely.
  *
  * The lock value itself is stored in Object.lock, which is a union of
  * the form:
@@ -105,25 +106,20 @@
  *         Monitor*    mon;
  *     } Lock;
  *
- * It is possible to tell the current state of the lock from the actual
- * value, so we do not need to store any additional state.  When the
- * lock is "thin", it has the form:
+ * The LSB of the lock value encodes its state.  If cleared, the lock
+ * is in the "thin" state and its bits are formatted as follows:
+ * 
+ *    [31 ---- 19] [18 ---- 3] [2 ---- 1] [0]
+ *     lock count   thread id  hash state  0
  *
- *     [31 ---- 16] [15 ---- 1] [0]
- *      lock count   thread id   1
+ * If set, the lock is in the "fat" state and its bits are formatted
+ * as follows:
  *
- * When it is "fat", the field is simply a (Monitor *).  Since the pointer
- * will always be 4-byte-aligned, bits 1 and 0 will always be zero when
- * the field holds a pointer.  Hence, we can tell the current fat-vs-thin
- * state by checking the least-significant bit.
+ *    [31 ---- 3] [2 ---- 1] [0]
+ *      pointer   hash state  1
  *
  * For an in-depth description of the mechanics of thin-vs-fat locking,
  * read the paper referred to above.
- *
- * To reduce the amount of work when attempting a compare and exchange,
- * Thread.threadId is guaranteed to have bit 0 set, and all new Objects
- * have their lock fields initialized to the value 0x1, or
- * DVM_LOCK_INITIAL_THIN_VALUE, via DVM_OBJECT_INIT().
  */
 
 /*
@@ -188,6 +184,10 @@
         LOGE("Unable to allocate monitor\n");
         dvmAbort();
     }
+    if (((u4)mon & 7) != 0) {
+        LOGE("Misaligned monitor: %p\n", mon);
+        dvmAbort();
+    }
     mon->obj = obj;
     dvmInitMutex(&mon->lock);
     pthread_cond_init(&mon->cond, NULL);
@@ -275,6 +275,8 @@
  */
 bool dvmHoldsLock(Thread* thread, Object* obj)
 {
+    u4 thin;
+
     if (thread == NULL || obj == NULL) {
         return false;
     }
@@ -283,11 +285,11 @@
      * latch it so that it doesn't change out from under
      * us if we get preempted.
      */
-    Lock lock = obj->lock;
-    if (IS_LOCK_FAT(&lock)) {
-        return thread == lock.mon->owner;
+    thin = obj->lock.thin;
+    if (LW_SHAPE(thin) == LW_SHAPE_FAT) {
+        return thread == LW_MONITOR(thin)->owner;
     } else {
-        return thread->threadId == (lock.thin & 0xffff);
+        return thread->threadId == LW_LOCK_OWNER(thin);
     }
 }
 
@@ -305,10 +307,10 @@
 
 #ifdef WITH_DEADLOCK_PREDICTION
     if (gDvm.deadlockPredictMode != kDPOff)
-        removeCollectedObject(lock->mon->obj);
+        removeCollectedObject(LW_MONITOR(lock->thin)->obj);
 #endif
 
-    mon = lock->mon;
+    mon = LW_MONITOR(lock->thin);
     lock->thin = DVM_LOCK_INITIAL_THIN_VALUE;
 
     /* This lock is associated with an object
@@ -468,8 +470,8 @@
     bool timed;
     int cc;
 
-    /* Make sure that the lock is fat and that we hold it. */
-    if (mon == NULL || ((u4)mon & 1) != 0 || mon->owner != self) {
+    /* Make sure that we hold the lock. */
+    if (mon == NULL || mon->owner != self) {
         dvmThrowException("Ljava/lang/IllegalMonitorStateException;",
             "object not locked by thread before wait()");
         return;
@@ -674,8 +676,8 @@
  */
 static void notifyMonitor(Thread* self, Monitor* mon)
 {
-    /* Make sure that the lock is fat and that we hold it. */
-    if (mon == NULL || ((u4)mon & 1) != 0 || mon->owner != self) {
+    /* Make sure that we hold the lock. */
+    if (mon == NULL || mon->owner != self) {
         dvmThrowException("Ljava/lang/IllegalMonitorStateException;",
             "object not locked by thread before notify()");
         return;
@@ -708,8 +710,8 @@
  */
 static void notifyAllMonitor(Thread* self, Monitor* mon)
 {
-    /* Make sure that the lock is fat and that we hold it. */
-    if (mon == NULL || ((u4)mon & 1) != 0 || mon->owner != self) {
+    /* Make sure that we hold the lock. */
+    if (mon == NULL || mon->owner != self) {
         dvmThrowException("Ljava/lang/IllegalMonitorStateException;",
             "object not locked by thread before notifyAll()");
         return;
@@ -729,11 +731,6 @@
     }
 }
 
-#if THIN_LOCKING
-/*
- * Thin locking support
- */
-
 /*
  * Implements monitorenter for "synchronized" stuff.
  *
@@ -743,36 +740,40 @@
 void dvmLockObject(Thread* self, Object *obj)
 {
     volatile u4 *thinp = &obj->lock.thin;
+    u4 thin;
     u4 threadId = self->threadId;
+    Monitor *mon;
 
     /* First, try to grab the lock as if it's thin;
      * 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);
     if (!ATOMIC_CMP_SWAP((int32_t *)thinp,
                          (int32_t)DVM_LOCK_INITIAL_THIN_VALUE,
-                         (int32_t)threadId)) {
+                         (int32_t)thin)) {
         /* The lock is either a thin lock held by someone (possibly 'self'),
          * or a fat lock.
          */
-        if ((*thinp & 0xffff) == threadId) {
+        if (LW_LOCK_OWNER(*thinp) == threadId) {
             /* 'self' is already holding the thin lock; we can just
              * bump the count.  Atomic operations are not necessary
              * because only the thread holding the lock is allowed
              * to modify the Lock field.
              */
-            *thinp += 1<<16;
+            *thinp += 1 << LW_LOCK_COUNT_SHIFT;
         } else {
             /* If this is a thin lock we need to spin on it, if it's fat
              * we need to acquire the monitor.
              */
-            if ((*thinp & 1) != 0) {
+            if (LW_SHAPE(*thinp) == LW_SHAPE_THIN) {
                 ThreadStatus oldStatus;
                 static const unsigned long maxSleepDelay = 1 * 1024 * 1024;
                 unsigned long sleepDelay;
 
                 LOG_THIN("(%d) spin on lock 0x%08x: 0x%08x (0x%08x) 0x%08x\n",
                          threadId, (uint)&obj->lock,
-                         DVM_LOCK_INITIAL_THIN_VALUE, *thinp, threadId);
+                         DVM_LOCK_INITIAL_THIN_VALUE, *thinp, thin);
 
                 /* The lock is still thin, but some other thread is
                  * holding it.  Let the VM know that we're about
@@ -788,8 +789,8 @@
                      * we need to watch out for some other thread
                      * fattening the lock behind our back.
                      */
-                    while (*thinp != DVM_LOCK_INITIAL_THIN_VALUE) {
-                        if ((*thinp & 1) == 0) {
+                    while (LW_LOCK_OWNER(*thinp) != 0) {
+                        if (LW_SHAPE(*thinp) == LW_SHAPE_FAT) {
                             /* The lock has been fattened already.
                              */
                             LOG_THIN("(%d) lock 0x%08x surprise-fattened\n",
@@ -808,13 +809,15 @@
                             }
                         }
                     }
+                    thin = threadId << LW_LOCK_OWNER_SHIFT;
+                    thin |= *thinp & (LW_HASH_STATE_MASK << LW_HASH_STATE_SHIFT);
                 } while (!ATOMIC_CMP_SWAP((int32_t *)thinp,
                                           (int32_t)DVM_LOCK_INITIAL_THIN_VALUE,
-                                          (int32_t)threadId));
+                                          (int32_t)thin));
                 LOG_THIN("(%d) spin on lock done 0x%08x: "
                          "0x%08x (0x%08x) 0x%08x\n",
                          threadId, (uint)&obj->lock,
-                         DVM_LOCK_INITIAL_THIN_VALUE, *thinp, threadId);
+                         DVM_LOCK_INITIAL_THIN_VALUE, *thinp, thin);
 
                 /* We've got the thin lock; let the VM know that we're
                  * done waiting.
@@ -825,7 +828,8 @@
                  * We could also create the monitor in an "owned" state
                  * to avoid "re-locking" it in fat_lock.
                  */
-                obj->lock.mon = dvmCreateMonitor(obj);
+                mon = dvmCreateMonitor(obj);
+                obj->lock.thin = (u4)mon | LW_SHAPE_FAT;
                 LOG_THIN("(%d) lock 0x%08x fattened\n",
                          threadId, (uint)&obj->lock);
 
@@ -837,8 +841,8 @@
              * that obj->lock.mon is a regular (Monitor *).
              */
         fat_lock:
-            assert(obj->lock.mon != NULL);
-            lockMonitor(self, obj->lock.mon);
+            assert(LW_MONITOR(obj->lock.thin) != NULL);
+            lockMonitor(self, LW_MONITOR(obj->lock.thin));
         }
     }
     // else, the lock was acquired with the ATOMIC_CMP_SWAP().
@@ -904,19 +908,21 @@
 {
     volatile u4 *thinp = &obj->lock.thin;
     u4 threadId = self->threadId;
+    u4 thin;
 
     /* Check the common case, where 'self' has locked 'obj' once, first.
      */
-    if (*thinp == threadId) {
+    thin = *thinp;
+    if (LW_LOCK_OWNER(thin) == threadId && LW_LOCK_COUNT(thin) == 0) {
         /* Unlock 'obj' by clearing our threadId from 'thin'.
          * The lock protects the lock field itself, so it's
          * safe to update non-atomically.
          */
-        *thinp = DVM_LOCK_INITIAL_THIN_VALUE;
-    } else if ((*thinp & 1) != 0) {
+        *thinp &= (LW_HASH_STATE_MASK << LW_HASH_STATE_SHIFT);
+    } else if (LW_SHAPE(*thinp) == LW_SHAPE_THIN) {
         /* If the object is locked, it had better be locked by us.
          */
-        if ((*thinp & 0xffff) != threadId) {
+        if (LW_LOCK_OWNER(*thinp) != threadId) {
             /* The JNI spec says that we should throw an exception
              * in this case.
              */
@@ -930,12 +936,12 @@
         /* It's a thin lock, but 'self' has locked 'obj'
          * more than once.  Decrement the count.
          */
-        *thinp -= 1<<16;
+        *thinp -= 1 << LW_LOCK_COUNT_SHIFT;
     } else {
         /* It's a fat lock.
          */
-        assert(obj->lock.mon != NULL);
-        if (!unlockMonitor(self, obj->lock.mon)) {
+        assert(LW_MONITOR(obj->lock.thin) != NULL);
+        if (!unlockMonitor(self, LW_MONITOR(obj->lock.thin))) {
             /* exception has been raised */
             return false;
         }
@@ -957,15 +963,15 @@
 void dvmObjectWait(Thread* self, Object *obj, s8 msec, s4 nsec,
     bool interruptShouldThrow)
 {
-    Monitor* mon = obj->lock.mon;
+    Monitor* mon = LW_MONITOR(obj->lock.thin);
     u4 thin = obj->lock.thin;
 
     /* If the lock is still thin, we need to fatten it.
      */
-    if ((thin & 1) != 0) {
+    if (LW_SHAPE(thin) == LW_SHAPE_THIN) {
         /* Make sure that 'self' holds the lock.
          */
-        if ((thin & 0xffff) != self->threadId) {
+        if (LW_LOCK_OWNER(thin) != self->threadId) {
             dvmThrowException("Ljava/lang/IllegalMonitorStateException;",
                 "object not locked by thread before wait()");
             return;
@@ -982,7 +988,7 @@
          * make sure that the monitor reflects this.
          */
         lockMonitor(self, mon);
-        mon->lockCount = thin >> 16;
+        mon->lockCount = LW_LOCK_COUNT(thin);
         LOG_THIN("(%d) lock 0x%08x fattened by wait() to count %d\n",
                  self->threadId, (uint)&obj->lock, mon->lockCount);
 
@@ -990,7 +996,7 @@
         /* Make the monitor public now that it's in the right state.
          */
         MEM_BARRIER();
-        obj->lock.mon = mon;
+        obj->lock.thin = (u4)mon | LW_SHAPE_FAT;
     }
 
     waitMonitor(self, mon, msec, nsec, interruptShouldThrow);
@@ -1001,16 +1007,15 @@
  */
 void dvmObjectNotify(Thread* self, Object *obj)
 {
-    Monitor* mon = obj->lock.mon;
     u4 thin = obj->lock.thin;
 
     /* If the lock is still thin, there aren't any waiters;
      * waiting on an object forces lock fattening.
      */
-    if ((thin & 1) != 0) {
+    if (LW_SHAPE(thin) == LW_SHAPE_THIN) {
         /* Make sure that 'self' holds the lock.
          */
-        if ((thin & 0xffff) != self->threadId) {
+        if (LW_LOCK_OWNER(thin) != self->threadId) {
             dvmThrowException("Ljava/lang/IllegalMonitorStateException;",
                 "object not locked by thread before notify()");
             return;
@@ -1021,7 +1026,7 @@
     } else {
         /* It's a fat lock.
          */
-        notifyMonitor(self, mon);
+        notifyMonitor(self, LW_MONITOR(thin));
     }
 }
 
@@ -1035,10 +1040,10 @@
     /* If the lock is still thin, there aren't any waiters;
      * waiting on an object forces lock fattening.
      */
-    if ((thin & 1) != 0) {
+    if (LW_SHAPE(thin) == LW_SHAPE_THIN) {
         /* Make sure that 'self' holds the lock.
          */
-        if ((thin & 0xffff) != self->threadId) {
+        if (LW_LOCK_OWNER(thin) != self->threadId) {
             dvmThrowException("Ljava/lang/IllegalMonitorStateException;",
                 "object not locked by thread before notifyAll()");
             return;
@@ -1047,82 +1052,12 @@
         /* no-op;  there are no waiters to notify.
          */
     } else {
-        Monitor* mon = obj->lock.mon;
-
         /* It's a fat lock.
          */
-        notifyAllMonitor(self, mon);
+        notifyAllMonitor(self, LW_MONITOR(thin));
     }
 }
 
-#else  // not THIN_LOCKING
-
-/*
- * Implements monitorenter for "synchronized" stuff.
- *
- * This does not fail or throw an exception.
- */
-void dvmLockObject(Thread* self, Object* obj)
-{
-    Monitor* mon = obj->lock.mon;
-
-    if (mon == NULL) {
-        mon = dvmCreateMonitor(obj);
-        if (!ATOMIC_CMP_SWAP((int32_t *)&obj->lock.mon,
-                             (int32_t)NULL, (int32_t)mon)) {
-            /* somebody else beat us to it */
-            releaseMonitor(mon);
-            mon = obj->lock.mon;
-        }
-    }
-
-    lockMonitor(self, mon);
-}
-
-/*
- * Implements monitorexit for "synchronized" stuff.
- */
-bool dvmUnlockObject(Thread* self, Object* obj)
-{
-    Monitor* mon = obj->lock.mon;
-
-    return unlockMonitor(self, mon);
-}
-
-
-/*
- * Object.wait().
- */
-void dvmObjectWait(Thread* self, Object* obj, u8 msec, u4 nsec)
-{
-    Monitor* mon = obj->lock.mon;
-
-    waitMonitor(self, mon, msec, nsec);
-}
-
-/*
- * Object.notify().
- */
-void dvmObjectNotify(Thread* self, Object* obj)
-{
-    Monitor* mon = obj->lock.mon;
-
-    notifyMonitor(self, mon);
-}
-
-/*
- * Object.notifyAll().
- */
-void dvmObjectNotifyAll(Thread* self, Object* obj)
-{
-    Monitor* mon = obj->lock.mon;
-
-    notifyAllMonitor(self, mon);
-}
-
-#endif  // not THIN_LOCKING
-
-
 /*
  * This implements java.lang.Thread.sleep(long msec, int nsec).
  *
@@ -1258,6 +1193,10 @@
     unlockMonitor(self, mon);
 }
 
+u4 dvmIdentityHashCode(Object *obj)
+{
+    return (u4)obj;
+}
 
 #ifdef WITH_DEADLOCK_PREDICTION
 /*
@@ -1670,10 +1609,10 @@
      */
     if (!IS_LOCK_FAT(&acqObj->lock)) {
         LOGVV("fattening lockee %p (recur=%d)\n",
-            acqObj, acqObj->lock.thin >> 16);
+            acqObj, LW_LOCK_COUNT(acqObj->lock.thin));
         Monitor* newMon = dvmCreateMonitor(acqObj);
         lockMonitor(self, newMon);      // can't stall, don't need VMWAIT
-        newMon->lockCount += acqObj->lock.thin >> 16;
+        newMon->lockCount += LW_LOCK_COUNT(acqObj->lock.thin);
         acqObj->lock.mon = newMon;
     }
 
@@ -1717,10 +1656,10 @@
      */
     if (!IS_LOCK_FAT(&mrl->obj->lock)) {
         LOGVV("fattening parent %p f/b/o child %p (recur=%d)\n",
-            mrl->obj, acqObj, mrl->obj->lock.thin >> 16);
+            mrl->obj, acqObj, LW_LOCK_COUNT(mrl->obj->lock.thin));
         Monitor* newMon = dvmCreateMonitor(mrl->obj);
         lockMonitor(self, newMon);      // can't stall, don't need VMWAIT
-        newMon->lockCount += mrl->obj->lock.thin >> 16;
+        newMon->lockCount += LW_LOCK_COUNT(mrl->obj->lock.thin);
         mrl->obj->lock.mon = newMon;
     }
 
diff --git a/vm/Sync.h b/vm/Sync.h
index 6baa46d..c3785b3 100644
--- a/vm/Sync.h
+++ b/vm/Sync.h
@@ -19,6 +19,29 @@
 #ifndef _DALVIK_SYNC
 #define _DALVIK_SYNC
 
+#define LW_SHAPE_THIN 0
+#define LW_SHAPE_FAT 1
+#define LW_SHAPE_MASK 0x1
+#define LW_SHAPE(x) ((x) & LW_SHAPE_MASK)
+
+#define LW_HASH_STATE_UNHASHED 0
+#define LW_HASH_STATE_HASHED 1
+#define LW_HASH_STATE_HASHED_AND_MOVED 2
+#define LW_HASH_STATE_MASK 0x3
+#define LW_HASH_STATE_SHIFT 1
+#define LW_HASH_STATE(x) (((x) >> LW_HASH_STATE_SHIFT) & LW_HASH_STATE_MASK)
+
+#define LW_MONITOR(x) \
+  ((Monitor*)((x) & ~((LW_HASH_STATE_MASK << LW_HASH_STATE_SHIFT) | LW_SHAPE_MASK)))
+
+#define LW_LOCK_OWNER_MASK 0xffff
+#define LW_LOCK_OWNER_SHIFT 3
+#define LW_LOCK_OWNER(x) (((x) >> LW_LOCK_OWNER_SHIFT) & LW_LOCK_OWNER_MASK)
+
+#define LW_LOCK_COUNT_MASK 0x1fff
+#define LW_LOCK_COUNT_SHIFT 19
+#define LW_LOCK_COUNT(x) (((x) >> LW_LOCK_COUNT_SHIFT) & LW_LOCK_COUNT_MASK)
+
 struct Object;
 struct Monitor;
 struct Thread;
@@ -42,19 +65,15 @@
  * Initialize a Lock to the proper starting value.
  * This is necessary for thin locking.
  */
-#define THIN_LOCKING 1
-#if THIN_LOCKING
-#define DVM_LOCK_INITIAL_THIN_VALUE (0x1)
-#else
 #define DVM_LOCK_INITIAL_THIN_VALUE (0)
-#endif
+
 #define DVM_LOCK_INIT(lock) \
     do { (lock)->thin = DVM_LOCK_INITIAL_THIN_VALUE; } while (0)
 
 /*
  * Returns true if the lock has been fattened.
  */
-#define IS_LOCK_FAT(lock)   (((lock)->thin & 1) == 0 && (lock)->mon != NULL)
+#define IS_LOCK_FAT(lock)   (LW_SHAPE((lock)->thin) == LW_SHAPE_FAT)
 
 /*
  * Acquire the object's monitor.
@@ -75,6 +94,11 @@
 void dvmObjectNotifyAll(struct Thread* self, struct Object* obj);
 
 /*
+ * Implementation of System.identityHashCode().
+ */
+u4 dvmIdentityHashCode(struct Object* obj);
+
+/*
  * Implementation of Thread.sleep().
  */
 void dvmThreadSleep(u8 msec, u4 nsec);
diff --git a/vm/alloc/MarkSweep.c b/vm/alloc/MarkSweep.c
index a3279d8..429665f 100644
--- a/vm/alloc/MarkSweep.c
+++ b/vm/alloc/MarkSweep.c
@@ -820,8 +820,6 @@
     const int offReferent = gDvm.offJavaLangRefReference_referent;
     bool workRequired = false;
 
-size_t numCleared = 0;
-size_t numEnqueued = 0;
     reference = refListHead;
     while (reference != NULL) {
         Object *next;
@@ -888,8 +886,6 @@
                 schedEnqueue = false;
                 break;
             }
-numCleared += schedClear ? 1 : 0;
-numEnqueued += schedEnqueue ? 1 : 0;
 
             if (schedClear || schedEnqueue) {
                 uintptr_t workBits;
@@ -929,11 +925,6 @@
 
         reference = next;
     }
-#define refType2str(r) \
-    ((r) == REF_SOFT ? "soft" : ( \
-     (r) == REF_WEAK ? "weak" : ( \
-     (r) == REF_PHANTOM ? "phantom" : "UNKNOWN" )))
-LOGD_HEAP("dvmHeapHandleReferences(): cleared %zd, enqueued %zd %s references\n", numCleared, numEnqueued, refType2str(refType));
 
     /* Walk though the reference list again, and mark any non-clear/marked
      * referents.  Only PhantomReferences can have non-clear referents
diff --git a/vm/compiler/codegen/arm/CodegenDriver.c b/vm/compiler/codegen/arm/CodegenDriver.c
index f3648b9..249970c 100644
--- a/vm/compiler/codegen/arm/CodegenDriver.c
+++ b/vm/compiler/codegen/arm/CodegenDriver.c
@@ -2098,7 +2098,7 @@
         }
         case OP_MONITOR_EXIT:
         case OP_MONITOR_ENTER:
-#if defined(WITH_DEADLOCK_PREDICTION) || defined(WITH_MONITOR_TRACKING)
+#if 1 || defined(WITH_DEADLOCK_PREDICTION) || defined(WITH_MONITOR_TRACKING)
             genMonitorPortable(cUnit, mir);
 #else
             genMonitor(cUnit, mir);
diff --git a/vm/compiler/codegen/arm/Thumb2/Gen.c b/vm/compiler/codegen/arm/Thumb2/Gen.c
index 579b0ea..9251364 100644
--- a/vm/compiler/codegen/arm/Thumb2/Gen.c
+++ b/vm/compiler/codegen/arm/Thumb2/Gen.c
@@ -180,7 +180,6 @@
  */
 static void genMonitor(CompilationUnit *cUnit, MIR *mir)
 {
-#if defined (THIN_LOCKING)
     RegLocation rlSrc = getSrcLoc(cUnit, mir, 0);
     bool enter = (mir->dalvikInsn.opCode == OP_MONITOR_ENTER);
     ArmLIR *target;
@@ -229,9 +228,6 @@
     target = newLIR0(cUnit, kArmPseudoTargetLabel);
     target->defMask = ENCODE_ALL;
     branch->generic.target = (LIR *)target;
-#else
-    genMonitorPortable(cUnit, mir);
-#endif
 }
 
 /*
diff --git a/vm/native/InternalNative.c b/vm/native/InternalNative.c
index 735cf96..9b6b801 100644
--- a/vm/native/InternalNative.c
+++ b/vm/native/InternalNative.c
@@ -285,15 +285,6 @@
 }
 
 
-/*
- * Return the hash code for the specified object.
- */
-u4 dvmGetObjectHashCode(Object* obj)
-{
-    return (u4) obj;
-}
-
-
 #define NUM_DOPRIV_FUNCS    4
 
 /*
diff --git a/vm/native/InternalNativePriv.h b/vm/native/InternalNativePriv.h
index abfda6c..bcd9119 100644
--- a/vm/native/InternalNativePriv.h
+++ b/vm/native/InternalNativePriv.h
@@ -77,11 +77,6 @@
  */
 bool dvmIsPrivilegedMethod(const Method* method);
 
-/*
- * Return the hash code for the specified object.
- */
-u4 dvmGetObjectHashCode(Object* obj);
-
 
 /*
  * Tables of methods.
diff --git a/vm/native/java_lang_Object.c b/vm/native/java_lang_Object.c
index 89e219f..44f581e 100644
--- a/vm/native/java_lang_Object.c
+++ b/vm/native/java_lang_Object.c
@@ -42,7 +42,7 @@
 static void Dalvik_java_lang_Object_hashCode(const u4* args, JValue* pResult)
 {
     Object* thisPtr = (Object*) args[0];
-    RETURN_INT(dvmGetObjectHashCode(thisPtr));
+    RETURN_INT(dvmIdentityHashCode(thisPtr));
 }
 
 /*
diff --git a/vm/native/java_lang_System.c b/vm/native/java_lang_System.c
index b26a368..e2533ed 100644
--- a/vm/native/java_lang_System.c
+++ b/vm/native/java_lang_System.c
@@ -245,7 +245,7 @@
     JValue* pResult)
 {
     Object* thisPtr = (Object*) args[0];
-    RETURN_INT(dvmGetObjectHashCode(thisPtr));
+    RETURN_INT(dvmIdentityHashCode(thisPtr));
 }
 
 /*