OSDN Git Service

Remove the unused monitor tracking and deadlock prediction code.
authorCarl Shapiro <cshapiro@google.com>
Tue, 1 Feb 2011 19:32:44 +0000 (11:32 -0800)
committerCarl Shapiro <cshapiro@google.com>
Tue, 1 Feb 2011 19:32:44 +0000 (11:32 -0800)
This feature has been in the code base for several releases but has never
been enabled.

Change-Id: Ia770b03ebc90a3dc7851c0cd8ef301f9762f50db

22 files changed:
docs/embedded-vm-control.html
vm/Dvm.mk
vm/Globals.h
vm/Init.c
vm/Sync.c
vm/Thread.c
vm/Thread.h
vm/compiler/codegen/arm/Codegen.h
vm/compiler/codegen/arm/CodegenDriver.c
vm/mterp/armv5te/OP_MONITOR_ENTER.S
vm/mterp/c/OP_MONITOR_ENTER.c
vm/mterp/out/InterpAsm-armv5te-vfp.S
vm/mterp/out/InterpAsm-armv5te.S
vm/mterp/out/InterpAsm-armv7-a-neon.S
vm/mterp/out/InterpAsm-armv7-a.S
vm/mterp/out/InterpAsm-x86-atom.S
vm/mterp/out/InterpAsm-x86.S
vm/mterp/out/InterpC-allstubs.c
vm/mterp/out/InterpC-portdbg.c
vm/mterp/out/InterpC-portstd.c
vm/mterp/x86-atom/OP_MONITOR_ENTER.S
vm/mterp/x86/OP_MONITOR_ENTER.S

index 11751e0..a0bdd29 100644 (file)
@@ -13,7 +13,6 @@
     <li><a href="#assertions">Assertions</a>
     <li><a href="#verifier">Bytecode Verification and Optimization</a>
     <li><a href="#execmode">Execution Mode</a>
-    <li><a href="#dp">Deadlock Prediction</a>
     <li><a href="#stackdump">Stack Dumps</a>
     <li><a href="#dexcheck">DEX File Checksums</a>
     <li><a href="#general">General Flags</a>
@@ -207,40 +206,6 @@ suspect that JIT compilation is causing your application to behave
 incorrectly.
 
 
-<h2><a name="dp">Deadlock Prediction</a></h2>
-
-<p>If the VM is built with <code>WITH_DEADLOCK_PREDICTION</code>, the deadlock
-predictor can be enabled with the <code>-Xdeadlockpredict</code> argument.
-(The output from <code>dalvikvm -help</code> will tell you if the VM was
-built appropriately -- look for <code>deadlock_prediction</code> on the
-<code>Configured with:</code> line.)
-This feature tells the VM to keep track of the order in which object
-monitor locks are acquired.  If the program attempts to acquire a set
-of locks in a different order from what was seen earlier, the VM logs
-a warning and optionally throws an exception.
-
-<p>Valid values for the command-line argument are
-<code>off</code> to disable it (default), <code>warn</code> to log the
-problem but continue executing, <code>err</code> to cause a
-<code>dalvik.system.PotentialDeadlockError</code> to be thrown from the
-<code>monitor-enter</code> instruction, and <code>abort</code> to have
-the entire VM abort.
-
-<p>You will usually want to use:
-<pre>adb shell setprop dalvik.vm.extra-opts -Xdeadlockpredict:err</pre>
-unless you are keeping an eye on the logs as they scroll by.
-
-<p>Please note that this feature is deadlock prediction, not deadlock
-detection -- in the current implementation, the computations are performed
-after the lock is acquired (this simplifies the code, reducing the
-overhead added to every mutex operation).  You can spot a deadlock in a
-hung process by sending a <code>kill -3</code> and examining the stack
-trace written to the log.
-
-<p>This only takes monitors into account.  Native mutexes and other resources
-can also be the cause of deadlocks, but will not be detected by this.
-
-
 <h2><a name="stackdump">Stack Dumps</a></h2>
 
 <p>Like other desktop VMs, when the Dalvik VM receives a SIGQUIT
index 9e3f33f..91d6b41 100644 (file)
--- a/vm/Dvm.mk
+++ b/vm/Dvm.mk
@@ -33,14 +33,6 @@ LOCAL_CFLAGS += -DARCH_VARIANT=\"$(dvm_arch_variant)\"
 # Optional features.  These may impact the size or performance of the VM.
 #
 
-ifeq ($(WITH_DEADLOCK_PREDICTION),true)
-  LOCAL_CFLAGS += -DWITH_DEADLOCK_PREDICTION
-  WITH_MONITOR_TRACKING := true
-endif
-ifeq ($(WITH_MONITOR_TRACKING),true)
-  LOCAL_CFLAGS += -DWITH_MONITOR_TRACKING
-endif
-
 # Make a debugging version when building the simulator (if not told
 # otherwise) and when explicitly asked.
 dvm_make_debug_vm := false
index 2a43b05..f96cbf2 100644 (file)
@@ -608,13 +608,6 @@ struct DvmGlobals {
     int             allocRecordHead;        /* most-recently-added entry */
     int             allocRecordCount;       /* #of valid entries */
 
-#ifdef WITH_DEADLOCK_PREDICTION
-    /* global lock on history tree accesses */
-    pthread_mutex_t deadlockHistoryLock;
-
-    enum { kDPOff=0, kDPWarn, kDPErr, kDPAbort } deadlockPredictMode;
-#endif
-
     /*
      * When normal control flow needs to be interrupted because
      * of an attached debugger, profiler, thread stop request, etc.,
index c2c0d5e..2b590bc 100644 (file)
--- a/vm/Init.c
+++ b/vm/Init.c
@@ -142,12 +142,6 @@ static void usage(const char* progName)
         " debugger"
         " profiler"
         " hprof"
-#ifdef WITH_MONITOR_TRACKING
-        " monitor_tracking"
-#endif
-#ifdef WITH_DEADLOCK_PREDICTION
-        " deadlock_prediction"
-#endif
 #ifdef WITH_TRACKREF_CHECKS
         " trackref_checks"
 #endif
@@ -965,24 +959,6 @@ static int processOptions(int argc, const char* const argv[],
           }
 #endif
 
-        } else if (strncmp(argv[i], "-Xdeadlockpredict:", 18) == 0) {
-#ifdef WITH_DEADLOCK_PREDICTION
-            if (strcmp(argv[i] + 18, "off") == 0)
-                gDvm.deadlockPredictMode = kDPOff;
-            else if (strcmp(argv[i] + 18, "warn") == 0)
-                gDvm.deadlockPredictMode = kDPWarn;
-            else if (strcmp(argv[i] + 18, "err") == 0)
-                gDvm.deadlockPredictMode = kDPErr;
-            else if (strcmp(argv[i] + 18, "abort") == 0)
-                gDvm.deadlockPredictMode = kDPAbort;
-            else {
-                dvmFprintf(stderr, "Bad value for -Xdeadlockpredict");
-                return -1;
-            }
-            if (gDvm.deadlockPredictMode != kDPOff)
-                LOGD("Deadlock prediction enabled (%s)\n", argv[i]+18);
-#endif
-
         } else if (strncmp(argv[i], "-Xstacktracefile:", 17) == 0) {
             gDvm.stackTraceFile = strdup(argv[i]+17);
 
index ff58aad..a33a71e 100644 (file)
--- a/vm/Sync.c
+++ b/vm/Sync.c
 
 #define LOG_THIN    LOGV
 
-#ifdef WITH_DEADLOCK_PREDICTION     /* fwd */
-static const char* kStartBanner =
-    "<-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#";
-static const char* kEndBanner =
-    "#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#->";
-
-/*
- * Unsorted, expanding list of objects.
- *
- * This is very similar to PointerSet (which came into existence after this),
- * but these are unsorted, uniqueness is not enforced by the "add" function,
- * and the base object isn't allocated on the heap.
- */
-typedef struct ExpandingObjectList {
-    u2          alloc;
-    u2          count;
-    Object**    list;
-} ExpandingObjectList;
-
-/* fwd */
-static void updateDeadlockPrediction(Thread* self, Object* obj);
-static void removeCollectedObject(Object* obj);
-static void expandObjClear(ExpandingObjectList* pList);
-#endif
-
 /*
  * Every Object has a monitor associated with it, but not every Object is
  * actually locked.  Even the ones that are locked do not need a
@@ -130,29 +105,6 @@ struct Monitor {
      */
     char*       ownerFileName;
     u4          ownerLineNumber;
-
-#ifdef WITH_DEADLOCK_PREDICTION
-    /*
-     * Objects that have been locked immediately after this one in the
-     * past.  We use an expanding flat array, allocated on first use, to
-     * minimize allocations.  Deletions from the list, expected to be
-     * infrequent, are crunched down.
-     */
-    ExpandingObjectList historyChildren;
-
-    /*
-     * We also track parents.  This isn't strictly necessary, but it makes
-     * the cleanup at GC time significantly faster.
-     */
-    ExpandingObjectList historyParents;
-
-    /* used during cycle detection */
-    bool        historyMark;
-
-    /* stack trace, established the first time we locked the object */
-    int         historyStackDepth;
-    int*        historyRawStackTrace;
-#endif
 };
 
 
@@ -195,12 +147,6 @@ void dvmFreeMonitorList(void)
     mon = gDvm.monitorList;
     while (mon != NULL) {
         nextMon = mon->next;
-
-#ifdef WITH_DEADLOCK_PREDICTION
-        expandObjClear(&mon->historyChildren);
-        expandObjClear(&mon->historyParents);
-        free(mon->historyRawStackTrace);
-#endif
         free(mon);
         mon = nextMon;
     }
@@ -302,11 +248,6 @@ static void freeObjectMonitor(Object* obj)
 
     assert(LW_SHAPE(obj->lock) == LW_SHAPE_FAT);
 
-#ifdef WITH_DEADLOCK_PREDICTION
-    if (gDvm.deadlockPredictMode != kDPOff)
-        removeCollectedObject(obj);
-#endif
-
     mon = LW_MONITOR(obj->lock);
     obj->lock = DVM_LOCK_INITIAL_THIN_VALUE;
 
@@ -320,11 +261,6 @@ static void freeObjectMonitor(Object* obj)
     assert(pthread_mutex_trylock(&mon->lock) == 0);
     assert(pthread_mutex_unlock(&mon->lock) == 0);
     dvmDestroyMutex(&mon->lock);
-#ifdef WITH_DEADLOCK_PREDICTION
-    expandObjClear(&mon->historyChildren);
-    expandObjClear(&mon->historyParents);
-    free(mon->historyRawStackTrace);
-#endif
     free(mon);
 }
 
@@ -339,9 +275,6 @@ void dvmSweepMonitorList(Monitor** mon, int (*isUnmarkedObject)(void*))
 
     assert(mon != NULL);
     assert(isUnmarkedObject != NULL);
-#ifdef WITH_DEADLOCK_PREDICTION
-    dvmDumpMonitorInfo("before monitor sweep");
-#endif
     prev = &handle;
     prev->next = curr = *mon;
     while (curr != NULL) {
@@ -355,9 +288,6 @@ void dvmSweepMonitorList(Monitor** mon, int (*isUnmarkedObject)(void*))
         }
     }
     *mon = handle.next;
-#ifdef WITH_DEADLOCK_PREDICTION
-    dvmDumpMonitorInfo("after monitor sweep");
-#endif
 }
 
 static char *logWriteInt(char *dst, int value)
@@ -1107,56 +1037,6 @@ retry:
         assert(LW_MONITOR(obj->lock) != NULL);
         lockMonitor(self, LW_MONITOR(obj->lock));
     }
-#ifdef WITH_DEADLOCK_PREDICTION
-    /*
-     * See if we were allowed to grab the lock at this time.  We do it
-     * *after* acquiring the lock, rather than before, so that we can
-     * freely update the Monitor struct.  This seems counter-intuitive,
-     * but our goal is deadlock *prediction* not deadlock *prevention*.
-     * (If we actually deadlock, the situation is easy to diagnose from
-     * a thread dump, so there's no point making a special effort to do
-     * the checks before the lock is held.)
-     *
-     * This needs to happen before we add the object to the thread's
-     * monitor list, so we can tell the difference between first-lock and
-     * re-lock.
-     *
-     * It's also important that we do this while in THREAD_RUNNING, so
-     * that we don't interfere with cleanup operations in the GC.
-     */
-    if (gDvm.deadlockPredictMode != kDPOff) {
-        if (self->status != THREAD_RUNNING) {
-            LOGE("Bad thread status (%d) in DP\n", self->status);
-            dvmDumpThread(self, false);
-            dvmAbort();
-        }
-        assert(!dvmCheckException(self));
-        updateDeadlockPrediction(self, obj);
-        if (dvmCheckException(self)) {
-            /*
-             * If we're throwing an exception here, we need to free the
-             * lock.  We add the object to the thread's monitor list so the
-             * "unlock" code can remove it.
-             */
-            dvmAddToMonitorList(self, obj, false);
-            dvmUnlockObject(self, obj);
-            LOGV("--- unlocked, pending is '%s'\n",
-                dvmGetException(self)->clazz->descriptor);
-        }
-    }
-
-    /*
-     * Add the locked object, and the current stack trace, to the list
-     * held by the Thread object.  If deadlock prediction isn't on,
-     * don't capture the stack trace.
-     */
-    dvmAddToMonitorList(self, obj, gDvm.deadlockPredictMode != kDPOff);
-#elif defined(WITH_MONITOR_TRACKING)
-    /*
-     * Add the locked object to the list held by the Thread object.
-     */
-    dvmAddToMonitorList(self, obj, false);
-#endif
 }
 
 /*
@@ -1222,14 +1102,6 @@ bool dvmUnlockObject(Thread* self, Object *obj)
             return false;
         }
     }
-
-#ifdef WITH_MONITOR_TRACKING
-    /*
-     * Remove the object from the Thread's list.
-     */
-    dvmRemoveFromMonitorList(self, obj);
-#endif
-
     return true;
 }
 
@@ -1546,593 +1418,3 @@ retry:
     return 0;  /* Quiet the compiler. */
 }
 #endif  /* WITH_COPYING_GC */
-
-#ifdef WITH_DEADLOCK_PREDICTION
-/*
- * ===========================================================================
- *      Deadlock prediction
- * ===========================================================================
- */
-/*
-The idea is to predict the possibility of deadlock by recording the order
-in which monitors are acquired.  If we see an attempt to acquire a lock
-out of order, we can identify the locks and offending code.
-
-To make this work, we need to keep track of the locks held by each thread,
-and create history trees for each lock.  When a thread tries to acquire
-a new lock, we walk through the "history children" of the lock, looking
-for a match with locks the thread already holds.  If we find a match,
-it means the thread has made a request that could result in a deadlock.
-
-To support recursive locks, we always allow re-locking a currently-held
-lock, and maintain a recursion depth count.
-
-An ASCII-art example, where letters represent Objects:
-
-        A
-       /|\
-      / | \
-     B  |  D
-      \ |
-       \|
-        C
-
-The above is the tree we'd have after handling Object synchronization
-sequences "ABC", "AC", "AD".  A has three children, {B, C, D}.  C is also
-a child of B.  (The lines represent pointers between parent and child.
-Every node can have multiple parents and multiple children.)
-
-If we hold AC, and want to lock B, we recursively search through B's
-children to see if A or C appears.  It does, so we reject the attempt.
-(A straightforward way to implement it: add a link from C to B, then
-determine whether the graph starting at B contains a cycle.)
-
-If we hold AC and want to lock D, we would succeed, creating a new link
-from C to D.
-
-The lock history and a stack trace is attached to the Object's Monitor
-struct, which means we need to fatten every Object we lock (thin locking
-is effectively disabled).  If we don't need the stack trace we can
-avoid fattening the leaf nodes, only fattening objects that need to hold
-history trees.
-
-Updates to Monitor structs are only allowed for the thread that holds
-the Monitor, so we actually do most of our deadlock prediction work after
-the lock has been acquired.
-
-When an object with a monitor is GCed, we need to remove it from the
-history trees.  There are two basic approaches:
- (1) For through the entire set of known monitors, search all child
-     lists for the object in question.  This is rather slow, resulting
-     in GC passes that take upwards of 10 seconds to complete.
- (2) Maintain "parent" pointers in each node.  Remove the entries as
-     required.  This requires additional storage and maintenance for
-     every operation, but is significantly faster at GC time.
-For each GCed object, we merge all of the object's children into each of
-the object's parents.
-*/
-
-#if !defined(WITH_MONITOR_TRACKING)
-# error "WITH_DEADLOCK_PREDICTION requires WITH_MONITOR_TRACKING"
-#endif
-
-/*
- * Clear out the contents of an ExpandingObjectList, freeing any
- * dynamic allocations.
- */
-static void expandObjClear(ExpandingObjectList* pList)
-{
-    if (pList->list != NULL) {
-        free(pList->list);
-        pList->list = NULL;
-    }
-    pList->alloc = pList->count = 0;
-}
-
-/*
- * Get the number of objects currently stored in the list.
- */
-static inline int expandBufGetCount(const ExpandingObjectList* pList)
-{
-    return pList->count;
-}
-
-/*
- * Get the Nth entry from the list.
- */
-static inline Object* expandBufGetEntry(const ExpandingObjectList* pList,
-    int i)
-{
-    return pList->list[i];
-}
-
-/*
- * Add a new entry to the list.
- *
- * We don't check for or try to enforce uniqueness.  It's expected that
- * the higher-level code does this for us.
- */
-static void expandObjAddEntry(ExpandingObjectList* pList, Object* obj)
-{
-    if (pList->count == pList->alloc) {
-        /* time to expand */
-        Object** newList;
-
-        if (pList->alloc == 0)
-            pList->alloc = 4;
-        else
-            pList->alloc *= 2;
-        LOGVV("expanding %p to %d\n", pList, pList->alloc);
-        newList = realloc(pList->list, pList->alloc * sizeof(Object*));
-        if (newList == NULL) {
-            LOGE("Failed expanding DP object list (alloc=%d)\n", pList->alloc);
-            dvmAbort();
-        }
-        pList->list = newList;
-    }
-
-    pList->list[pList->count++] = obj;
-}
-
-/*
- * Returns "true" if the element was successfully removed.
- */
-static bool expandObjRemoveEntry(ExpandingObjectList* pList, Object* obj)
-{
-    int i;
-
-    for (i = pList->count-1; i >= 0; i--) {
-        if (pList->list[i] == obj)
-            break;
-    }
-    if (i < 0)
-        return false;
-
-    if (i != pList->count-1) {
-        /*
-         * The order of elements is not important, so we just copy the
-         * last entry into the new slot.
-         */
-        //memmove(&pList->list[i], &pList->list[i+1],
-        //    (pList->count-1 - i) * sizeof(pList->list[0]));
-        pList->list[i] = pList->list[pList->count-1];
-    }
-
-    pList->count--;
-    pList->list[pList->count] = (Object*) 0xdecadead;
-    return true;
-}
-
-/*
- * Returns "true" if "obj" appears in the list.
- */
-static bool expandObjHas(const ExpandingObjectList* pList, Object* obj)
-{
-    int i;
-
-    for (i = 0; i < pList->count; i++) {
-        if (pList->list[i] == obj)
-            return true;
-    }
-    return false;
-}
-
-/*
- * Print the list contents to stdout.  For debugging.
- */
-static void expandObjDump(const ExpandingObjectList* pList)
-{
-    int i;
-    for (i = 0; i < pList->count; i++)
-        printf(" %p", pList->list[i]);
-}
-
-/*
- * Check for duplicate entries.  Returns the index of the first instance
- * of the duplicated value, or -1 if no duplicates were found.
- */
-static int expandObjCheckForDuplicates(const ExpandingObjectList* pList)
-{
-    int i, j;
-    for (i = 0; i < pList->count-1; i++) {
-        for (j = i + 1; j < pList->count; j++) {
-            if (pList->list[i] == pList->list[j]) {
-                return i;
-            }
-        }
-    }
-
-    return -1;
-}
-
-
-/*
- * Determine whether "child" appears in the list of objects associated
- * with the Monitor in "parent".  If "parent" is a thin lock, we return
- * false immediately.
- */
-static bool objectInChildList(const Object* parent, Object* child)
-{
-    u4 lock = parent->lock;
-    if (!IS_LOCK_FAT(&lock)) {
-        //LOGI("on thin\n");
-        return false;
-    }
-
-    return expandObjHas(&LW_MONITOR(lock)->historyChildren, child);
-}
-
-/*
- * Print the child list.
- */
-static void dumpKids(Object* parent)
-{
-    Monitor* mon = LW_MONITOR(parent->lock);
-
-    printf("Children of %p:", parent);
-    expandObjDump(&mon->historyChildren);
-    printf("\n");
-}
-
-/*
- * Add "child" to the list of children in "parent", and add "parent" to
- * the list of parents in "child".
- */
-static void linkParentToChild(Object* parent, Object* child)
-{
-    //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 = LW_MONITOR(parent->lock);
-    assert(!expandObjHas(&mon->historyChildren, child));
-    expandObjAddEntry(&mon->historyChildren, child);
-
-    mon = LW_MONITOR(child->lock);
-    assert(!expandObjHas(&mon->historyParents, parent));
-    expandObjAddEntry(&mon->historyParents, parent);
-}
-
-
-/*
- * Remove "child" from the list of children in "parent".
- */
-static void unlinkParentFromChild(Object* parent, Object* child)
-{
-    //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 = 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 = LW_MONITOR(child->lock);
-    if (!expandObjRemoveEntry(&mon->historyParents, parent)) {
-        LOGW("WARNING: parent %p not found in child %p\n", parent, child);
-    }
-    assert(!expandObjHas(&mon->historyParents, parent));
-    assert(expandObjCheckForDuplicates(&mon->historyParents) < 0);
-}
-
-
-/*
- * Log the monitors held by the current thread.  This is done as part of
- * flagging an error.
- */
-static void logHeldMonitors(Thread* self)
-{
-    char* name = NULL;
-
-    name = dvmGetThreadName(self);
-    LOGW("Monitors currently held by thread (threadid=%d '%s')\n",
-        self->threadId, name);
-    LOGW("(most-recently-acquired on top):\n");
-    free(name);
-
-    LockedObjectData* lod = self->pLockedObjects;
-    while (lod != NULL) {
-        LOGW("--- object %p[%d] (%s)\n",
-            lod->obj, lod->recursionCount, lod->obj->clazz->descriptor);
-        dvmLogRawStackTrace(lod->rawStackTrace, lod->stackDepth);
-
-        lod = lod->next;
-    }
-}
-
-/*
- * Recursively traverse the object hierarchy starting at "obj".  We mark
- * ourselves on entry and clear the mark on exit.  If we ever encounter
- * a marked object, we have a cycle.
- *
- * Returns "true" if all is well, "false" if we found a cycle.
- */
-static bool traverseTree(Thread* self, const Object* obj)
-{
-    assert(IS_LOCK_FAT(&obj->lock));
-    Monitor* mon = LW_MONITOR(obj->lock);
-
-    /*
-     * Have we been here before?
-     */
-    if (mon->historyMark) {
-        int* rawStackTrace;
-        int stackDepth;
-
-        LOGW("%s\n", kStartBanner);
-        LOGW("Illegal lock attempt:\n");
-        LOGW("--- object %p (%s)\n", obj, obj->clazz->descriptor);
-
-        rawStackTrace = dvmFillInStackTraceRaw(self, &stackDepth);
-        dvmLogRawStackTrace(rawStackTrace, stackDepth);
-        free(rawStackTrace);
-
-        LOGW(" ");
-        logHeldMonitors(self);
-
-        LOGW(" ");
-        LOGW("Earlier, the following lock order (from last to first) was\n");
-        LOGW("established -- stack trace is from first successful lock):\n");
-        return false;
-    }
-    mon->historyMark = true;
-
-    /*
-     * Examine the children.  We do NOT hold these locks, so they might
-     * very well transition from thin to fat or change ownership while
-     * we work.
-     *
-     * NOTE: we rely on the fact that they cannot revert from fat to thin
-     * while we work.  This is currently a safe assumption.
-     *
-     * We can safely ignore thin-locked children, because by definition
-     * they have no history and are leaf nodes.  In the current
-     * implementation we always fatten the locks to provide a place to
-     * hang the stack trace.
-     */
-    ExpandingObjectList* pList = &mon->historyChildren;
-    int i;
-    for (i = expandBufGetCount(pList)-1; i >= 0; i--) {
-        const Object* child = expandBufGetEntry(pList, i);
-        u4 lock = child->lock;
-        if (!IS_LOCK_FAT(&lock))
-            continue;
-        if (!traverseTree(self, child)) {
-            LOGW("--- object %p (%s)\n", obj, obj->clazz->descriptor);
-            dvmLogRawStackTrace(mon->historyRawStackTrace,
-                mon->historyStackDepth);
-            mon->historyMark = false;
-            return false;
-        }
-    }
-
-    mon->historyMark = false;
-
-    return true;
-}
-
-/*
- * Update the deadlock prediction tree, based on the current thread
- * acquiring "acqObj".  This must be called before the object is added to
- * the thread's list of held monitors.
- *
- * If the thread already holds the lock (recursion), or this is a known
- * lock configuration, we return without doing anything.  Otherwise, we add
- * a link from the most-recently-acquired lock in this thread to "acqObj"
- * after ensuring that the parent lock is "fat".
- *
- * This MUST NOT be called while a GC is in progress in another thread,
- * because we assume exclusive access to history trees in owned monitors.
- */
-static void updateDeadlockPrediction(Thread* self, Object* acqObj)
-{
-    LockedObjectData* lod;
-    LockedObjectData* mrl;
-
-    /*
-     * Quick check for recursive access.
-     */
-    lod = dvmFindInMonitorList(self, acqObj);
-    if (lod != NULL) {
-        LOGV("+++ DP: recursive %p\n", acqObj);
-        return;
-    }
-
-    /*
-     * Make the newly-acquired object's monitor "fat".  In some ways this
-     * isn't strictly necessary, but we need the GC to tell us when
-     * "interesting" objects go away, and right now the only way to make
-     * an object look interesting is to give it a monitor.
-     *
-     * This also gives us a place to hang a stack trace.
-     *
-     * Our thread holds the lock, so we're allowed to rewrite the lock
-     * without worrying that something will change out from under us.
-     */
-    if (!IS_LOCK_FAT(&acqObj->lock)) {
-        LOGVV("fattening lockee %p (recur=%d)\n",
-            acqObj, LW_LOCK_COUNT(acqObj->lock.thin));
-        inflateMonitor(self, acqObj);
-    }
-
-    /* if we don't have a stack trace for this monitor, establish one */
-    if (LW_MONITOR(acqObj->lock)->historyRawStackTrace == NULL) {
-        Monitor* mon = LW_MONITOR(acqObj->lock);
-        mon->historyRawStackTrace = dvmFillInStackTraceRaw(self,
-            &mon->historyStackDepth);
-    }
-
-    /*
-     * We need to examine and perhaps modify the most-recently-locked
-     * monitor.  We own that, so there's no risk of another thread
-     * stepping on us.
-     *
-     * Retrieve the most-recently-locked entry from our thread.
-     */
-    mrl = self->pLockedObjects;
-    if (mrl == NULL)
-        return;         /* no other locks held */
-
-    /*
-     * Do a quick check to see if "acqObj" is a direct descendant.  We can do
-     * this without holding the global lock because of our assertion that
-     * a GC is not running in parallel -- nobody except the GC can
-     * modify a history list in a Monitor they don't own, and we own "mrl".
-     * (There might be concurrent *reads*, but no concurrent *writes.)
-     *
-     * If we find it, this is a known good configuration, and we're done.
-     */
-    if (objectInChildList(mrl->obj, acqObj))
-        return;
-
-    /*
-     * "mrl" is going to need to have a history tree.  If it's currently
-     * a thin lock, we make it fat now.  The thin lock might have a
-     * nonzero recursive lock count, which we need to carry over.
-     *
-     * Our thread holds the lock, so we're allowed to rewrite the lock
-     * without worrying that something will change out from under us.
-     */
-    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));
-        inflateMonitor(self, mrl->obj);
-    }
-
-    /*
-     * We haven't seen this configuration before.  We need to scan down
-     * acqObj's tree to see if any of the monitors in self->pLockedObjects
-     * appear.  We grab a global lock before traversing or updating the
-     * history list.
-     *
-     * If we find a match for any of our held locks, we know that the lock
-     * has previously been acquired *after* acqObj, and we throw an error.
-     *
-     * The easiest way to do this is to create a link from "mrl" to "acqObj"
-     * and do a recursive traversal, marking nodes as we cross them.  If
-     * we cross one a second time, we have a cycle and can throw an error.
-     * (We do the flag-clearing traversal before adding the new link, so
-     * that we're guaranteed to terminate.)
-     *
-     * If "acqObj" is a thin lock, it has no history, and we can create a
-     * link to it without additional checks.  [ We now guarantee that it's
-     * always fat. ]
-     */
-    bool failed = false;
-    dvmLockMutex(&gDvm.deadlockHistoryLock);
-    linkParentToChild(mrl->obj, acqObj);
-    if (!traverseTree(self, acqObj)) {
-        LOGW("%s\n", kEndBanner);
-        failed = true;
-
-        /* remove the entry so we're still okay when in "warning" mode */
-        unlinkParentFromChild(mrl->obj, acqObj);
-    }
-    dvmUnlockMutex(&gDvm.deadlockHistoryLock);
-
-    if (failed) {
-        switch (gDvm.deadlockPredictMode) {
-        case kDPErr:
-            dvmThrowException("Ldalvik/system/PotentialDeadlockError;", NULL);
-            break;
-        case kDPAbort:
-            LOGE("Aborting due to potential deadlock\n");
-            dvmAbort();
-            break;
-        default:
-            /* warn only */
-            break;
-        }
-    }
-}
-
-/*
- * We're removing "child" from existence.  We want to pull all of
- * child's children into "parent", filtering out duplicates.  This is
- * called during the GC.
- *
- * This does not modify "child", which might have multiple parents.
- */
-static void mergeChildren(Object* parent, const Object* child)
-{
-    Monitor* mon;
-    int i;
-
-    assert(IS_LOCK_FAT(&child->lock));
-    mon = LW_MONITOR(child->lock);
-    ExpandingObjectList* pList = &mon->historyChildren;
-
-    for (i = expandBufGetCount(pList)-1; i >= 0; i--) {
-        Object* grandChild = expandBufGetEntry(pList, i);
-
-        if (!objectInChildList(parent, grandChild)) {
-            LOGVV("+++  migrating %p link to %p\n", grandChild, parent);
-            linkParentToChild(parent, grandChild);
-        } else {
-            LOGVV("+++  parent %p already links to %p\n", parent, grandChild);
-        }
-    }
-}
-
-/*
- * An object with a fat lock is being collected during a GC pass.  We
- * want to remove it from any lock history trees that it is a part of.
- *
- * This may require updating the history trees in several monitors.  The
- * monitor semantics guarantee that no other thread will be accessing
- * the history trees at the same time.
- */
-static void removeCollectedObject(Object* obj)
-{
-    Monitor* mon;
-
-    LOGVV("+++ collecting %p\n", obj);
-
-    /*
-     * For every parent of this object:
-     *  - merge all of our children into the parent's child list (creates
-     *    a two-way link between parent and child)
-     *  - remove ourselves from the parent's child list
-     */
-    ExpandingObjectList* pList;
-    int i;
-
-    assert(IS_LOCK_FAT(&obj->lock));
-    mon = LW_MONITOR(obj->lock);
-    pList = &mon->historyParents;
-    for (i = expandBufGetCount(pList)-1; i >= 0; i--) {
-        Object* parent = expandBufGetEntry(pList, i);
-        Monitor* parentMon = LW_MONITOR(parent->lock);
-
-        if (!expandObjRemoveEntry(&parentMon->historyChildren, obj)) {
-            LOGW("WARNING: child %p not found in parent %p\n", obj, parent);
-        }
-        assert(!expandObjHas(&parentMon->historyChildren, obj));
-
-        mergeChildren(parent, obj);
-    }
-
-    /*
-     * For every child of this object:
-     *  - remove ourselves from the child's parent list
-     */
-    pList = &mon->historyChildren;
-    for (i = expandBufGetCount(pList)-1; i >= 0; i--) {
-        Object* child = expandBufGetEntry(pList, i);
-        Monitor* childMon = LW_MONITOR(child->lock);
-
-        if (!expandObjRemoveEntry(&childMon->historyParents, obj)) {
-            LOGW("WARNING: parent %p not found in child %p\n", obj, child);
-        }
-        assert(!expandObjHas(&childMon->historyParents, obj));
-    }
-}
-
-#endif /*WITH_DEADLOCK_PREDICTION*/
index 36c34f4..6745dae 100644 (file)
@@ -284,9 +284,6 @@ bool dvmThreadStartup(void)
     dvmInitMutex(&gDvm._threadSuspendLock);
     dvmInitMutex(&gDvm.threadSuspendCountLock);
     pthread_cond_init(&gDvm.threadSuspendCountCond, NULL);
-#ifdef WITH_DEADLOCK_PREDICTION
-    dvmInitMutex(&gDvm.deadlockHistoryLock);
-#endif
 
     /*
      * Dedicated monitor for Thread.sleep().
@@ -3622,29 +3619,6 @@ void dvmDumpThreadEx(const DebugOutputTarget* target, Thread* thread,
         schedstatBuf, procStatData.utime, procStatData.stime,
         procStatData.processor);
 
-#ifdef WITH_MONITOR_TRACKING
-    if (!isRunning) {
-        LockedObjectData* lod = thread->pLockedObjects;
-        if (lod != NULL)
-            dvmPrintDebugMessage(target, "  | monitors held:\n");
-        else
-            dvmPrintDebugMessage(target, "  | monitors held: <none>\n");
-        while (lod != NULL) {
-            Object* obj = lod->obj;
-            if (obj->clazz == gDvm.classJavaLangClass) {
-                ClassObject* clazz = (ClassObject*) obj;
-                dvmPrintDebugMessage(target, "  >  %p[%d] (%s object for class %s)\n",
-                    obj, lod->recursionCount, obj->clazz->descriptor,
-                    clazz->descriptor);
-            } else {
-                dvmPrintDebugMessage(target, "  >  %p[%d] (%s)\n",
-                    obj, lod->recursionCount, obj->clazz->descriptor);
-            }
-            lod = lod->next;
-        }
-    }
-#endif
-
     if (isRunning)
         dvmDumpRunningThreadStack(target, thread);
     else
@@ -3786,130 +3760,3 @@ void dvmNukeThread(Thread* thread)
     signal(SIGSEGV, SIG_IGN);
     LOGD("Continuing\n");
 }
-
-#ifdef WITH_MONITOR_TRACKING
-/*
- * Count up the #of locked objects in the current thread.
- */
-static int getThreadObjectCount(const Thread* self)
-{
-    LockedObjectData* lod;
-    int count = 0;
-
-    lod = self->pLockedObjects;
-    while (lod != NULL) {
-        count++;
-        lod = lod->next;
-    }
-    return count;
-}
-
-/*
- * Add the object to the thread's locked object list if it doesn't already
- * exist.  The most recently added object is the most likely to be released
- * next, so we insert at the head of the list.
- *
- * If it already exists, we increase the recursive lock count.
- *
- * The object's lock may be thin or fat.
- */
-void dvmAddToMonitorList(Thread* self, Object* obj, bool withTrace)
-{
-    LockedObjectData* newLod;
-    LockedObjectData* lod;
-    int* trace;
-    int depth;
-
-    lod = self->pLockedObjects;
-    while (lod != NULL) {
-        if (lod->obj == obj) {
-            lod->recursionCount++;
-            LOGV("+++ +recursive lock %p -> %d\n", obj, lod->recursionCount);
-            return;
-        }
-        lod = lod->next;
-    }
-
-    newLod = (LockedObjectData*) calloc(1, sizeof(LockedObjectData));
-    if (newLod == NULL) {
-        LOGE("malloc failed on %d bytes\n", sizeof(LockedObjectData));
-        return;
-    }
-    newLod->obj = obj;
-    newLod->recursionCount = 0;
-
-    if (withTrace) {
-        trace = dvmFillInStackTraceRaw(self, &depth);
-        newLod->rawStackTrace = trace;
-        newLod->stackDepth = depth;
-    }
-
-    newLod->next = self->pLockedObjects;
-    self->pLockedObjects = newLod;
-
-    LOGV("+++ threadid=%d: added %p, now %d\n",
-        self->threadId, newLod, getThreadObjectCount(self));
-}
-
-/*
- * Remove the object from the thread's locked object list.  If the entry
- * has a nonzero recursion count, we just decrement the count instead.
- */
-void dvmRemoveFromMonitorList(Thread* self, Object* obj)
-{
-    LockedObjectData* lod;
-    LockedObjectData* prevLod;
-
-    lod = self->pLockedObjects;
-    prevLod = NULL;
-    while (lod != NULL) {
-        if (lod->obj == obj) {
-            if (lod->recursionCount > 0) {
-                lod->recursionCount--;
-                LOGV("+++ -recursive lock %p -> %d\n",
-                    obj, lod->recursionCount);
-                return;
-            } else {
-                break;
-            }
-        }
-        prevLod = lod;
-        lod = lod->next;
-    }
-
-    if (lod == NULL) {
-        LOGW("BUG: object %p not found in thread's lock list\n", obj);
-        return;
-    }
-    if (prevLod == NULL) {
-        /* first item in list */
-        assert(self->pLockedObjects == lod);
-        self->pLockedObjects = lod->next;
-    } else {
-        /* middle/end of list */
-        prevLod->next = lod->next;
-    }
-
-    LOGV("+++ threadid=%d: removed %p, now %d\n",
-        self->threadId, lod, getThreadObjectCount(self));
-    free(lod->rawStackTrace);
-    free(lod);
-}
-
-/*
- * If the specified object is already in the thread's locked object list,
- * return the LockedObjectData struct.  Otherwise return NULL.
- */
-LockedObjectData* dvmFindInMonitorList(const Thread* self, const Object* obj)
-{
-    LockedObjectData* lod;
-
-    lod = self->pLockedObjects;
-    while (lod != NULL) {
-        if (lod->obj == obj)
-            return lod;
-        lod = lod->next;
-    }
-    return NULL;
-}
-#endif /*WITH_MONITOR_TRACKING*/
index 5fdb869..bcd85a9 100644 (file)
@@ -32,10 +32,6 @@ int pthread_mutexattr_settype(pthread_mutexattr_t *attr, int type);
 enum { PTHREAD_MUTEX_ERRORCHECK = PTHREAD_MUTEX_ERRORCHECK_NP };
 #endif
 
-#ifdef WITH_MONITOR_TRACKING
-struct LockedObjectData;
-#endif
-
 /*
  * Current status; these map to JDWP constants, so don't rearrange them.
  * (If you do alter this, update the strings in dvmDumpThread and the
@@ -214,11 +210,6 @@ typedef struct Thread {
     /* JDWP invoke-during-breakpoint support */
     DebugInvokeReq  invokeReq;
 
-#ifdef WITH_MONITOR_TRACKING
-    /* objects locked by this thread; most recent is at head of list */
-    struct LockedObjectData* pLockedObjects;
-#endif
-
     /* base time for per-thread CPU timing (used by method profiling) */
     bool        cpuClockBaseSet;
     u8          cpuClockBase;
@@ -527,35 +518,4 @@ void dvmDumpAllThreadsEx(const DebugOutputTarget* target, bool grabLock);
  */
 void dvmNukeThread(Thread* thread);
 
-#ifdef WITH_MONITOR_TRACKING
-/*
- * Track locks held by the current thread, along with the stack trace at
- * the point the lock was acquired.
- *
- * At any given time the number of locks held across the VM should be
- * fairly small, so there's no reason not to generate and store the entire
- * stack trace.
- */
-typedef struct LockedObjectData {
-    /* the locked object */
-    struct Object*  obj;
-
-    /* number of times it has been locked recursively (zero-based ref count) */
-    int             recursionCount;
-
-    /* stack trace at point of initial acquire */
-    u4              stackDepth;
-    int*            rawStackTrace;
-
-    struct LockedObjectData* next;
-} LockedObjectData;
-
-/*
- * Add/remove/find objects from the thread's monitor list.
- */
-void dvmAddToMonitorList(Thread* self, Object* obj, bool withTrace);
-void dvmRemoveFromMonitorList(Thread* self, Object* obj);
-LockedObjectData* dvmFindInMonitorList(const Thread* self, const Object* obj);
-#endif
-
 #endif /*_DALVIK_THREAD*/
index 8522e62..330619b 100644 (file)
@@ -45,8 +45,7 @@ static bool genArithOpDoublePortable(CompilationUnit *cUnit, MIR *mir,
 
 static bool genConversionPortable(CompilationUnit *cUnit, MIR *mir);
 
-#if defined(WITH_DEADLOCK_PREDICTION) || defined(WITH_MONITOR_TRACKING) || \
-    defined(__ARM_ARCH_5__)
+#if defined(__ARM_ARCH_5__)
 static void genMonitorPortable(CompilationUnit *cUnit, MIR *mir);
 #endif
 
index 8e1b09c..fb7e30e 100644 (file)
@@ -1275,8 +1275,7 @@ static void genInterpSingleStep(CompilationUnit *cUnit, MIR *mir)
     opReg(cUnit, kOpBlx, r2);
 }
 
-#if defined(WITH_DEADLOCK_PREDICTION) || defined(WITH_MONITOR_TRACKING) || \
-    defined(_ARMV5TE) || defined(_ARMV5TE_VFP)
+#if defined(_ARMV5TE) || defined(_ARMV5TE_VFP)
 /*
  * To prevent a thread in a monitor wait from blocking the Jit from
  * resetting the code cache, heavyweight monitor lock will not
@@ -1301,11 +1300,7 @@ static void genMonitorPortable(CompilationUnit *cUnit, MIR *mir)
         /* Get dPC of next insn */
         loadConstant(cUnit, r4PC, (int)(cUnit->method->insns + mir->offset +
                  dexGetWidthFromOpcode(OP_MONITOR_ENTER)));
-#if defined(WITH_DEADLOCK_PREDICTION)
-        genDispatchToHandler(cUnit, TEMPLATE_MONITOR_ENTER_DEBUG);
-#else
         genDispatchToHandler(cUnit, TEMPLATE_MONITOR_ENTER);
-#endif
     } else {
         LOAD_FUNC_ADDR(cUnit, r2, (int)dvmUnlockObject);
         /* Do the call */
@@ -1810,11 +1805,7 @@ static bool handleFmt11x(CompilationUnit *cUnit, MIR *mir)
         }
         case OP_MONITOR_EXIT:
         case OP_MONITOR_ENTER:
-#if defined(WITH_DEADLOCK_PREDICTION) || defined(WITH_MONITOR_TRACKING)
-            genMonitorPortable(cUnit, mir);
-#else
             genMonitor(cUnit, mir);
-#endif
             break;
         case OP_THROW: {
             genInterpSingleStep(cUnit, mir);
index 36faabc..b3f74b0 100644 (file)
@@ -8,15 +8,9 @@
     GET_VREG(r1, r2)                    @ r1<- vAA (object)
     ldr     r0, [rGLUE, #offGlue_self]  @ r0<- glue->self
     cmp     r1, #0                      @ null object?
-    EXPORT_PC()                         @ need for precise GC, MONITOR_TRACKING
+    EXPORT_PC()                         @ need for precise GC
     beq     common_errNullObject        @ null object, throw an exception
     FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
     bl      dvmLockObject               @ call(self, obj)
-#ifdef WITH_DEADLOCK_PREDICTION /* implies WITH_MONITOR_TRACKING */
-    ldr     r0, [rGLUE, #offGlue_self]  @ r0<- glue->self
-    ldr     r1, [r0, #offThread_exception] @ check for exception
-    cmp     r1, #0
-    bne     common_exceptionThrown      @ exception raised, bail out
-#endif
     GET_INST_OPCODE(ip)                 @ extract opcode from rINST
     GOTO_OPCODE(ip)                     @ jump to next instruction
index c9d8999..de33483 100644 (file)
@@ -9,12 +9,8 @@ HANDLE_OPCODE(OP_MONITOR_ENTER /*vAA*/)
         if (!checkForNullExportPC(obj, fp, pc))
             GOTO_exceptionThrown();
         ILOGV("+ locking %p %s\n", obj, obj->clazz->descriptor);
-        EXPORT_PC();    /* need for precise GC, also WITH_MONITOR_TRACKING */
+        EXPORT_PC();    /* need for precise GC */
         dvmLockObject(self, obj);
-#ifdef WITH_DEADLOCK_PREDICTION
-        if (dvmCheckException(self))
-            GOTO_exceptionThrown();
-#endif
     }
     FINISH(1);
 OP_END
index 6cb5620..60fb6c3 100644 (file)
@@ -849,16 +849,10 @@ dalvik_inst:
     GET_VREG(r1, r2)                    @ r1<- vAA (object)
     ldr     r0, [rGLUE, #offGlue_self]  @ r0<- glue->self
     cmp     r1, #0                      @ null object?
-    EXPORT_PC()                         @ need for precise GC, MONITOR_TRACKING
+    EXPORT_PC()                         @ need for precise GC
     beq     common_errNullObject        @ null object, throw an exception
     FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
     bl      dvmLockObject               @ call(self, obj)
-#ifdef WITH_DEADLOCK_PREDICTION /* implies WITH_MONITOR_TRACKING */
-    ldr     r0, [rGLUE, #offGlue_self]  @ r0<- glue->self
-    ldr     r1, [r0, #offThread_exception] @ check for exception
-    cmp     r1, #0
-    bne     common_exceptionThrown      @ exception raised, bail out
-#endif
     GET_INST_OPCODE(ip)                 @ extract opcode from rINST
     GOTO_OPCODE(ip)                     @ jump to next instruction
 
index bf719ad..c869286 100644 (file)
@@ -849,16 +849,10 @@ dalvik_inst:
     GET_VREG(r1, r2)                    @ r1<- vAA (object)
     ldr     r0, [rGLUE, #offGlue_self]  @ r0<- glue->self
     cmp     r1, #0                      @ null object?
-    EXPORT_PC()                         @ need for precise GC, MONITOR_TRACKING
+    EXPORT_PC()                         @ need for precise GC
     beq     common_errNullObject        @ null object, throw an exception
     FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
     bl      dvmLockObject               @ call(self, obj)
-#ifdef WITH_DEADLOCK_PREDICTION /* implies WITH_MONITOR_TRACKING */
-    ldr     r0, [rGLUE, #offGlue_self]  @ r0<- glue->self
-    ldr     r1, [r0, #offThread_exception] @ check for exception
-    cmp     r1, #0
-    bne     common_exceptionThrown      @ exception raised, bail out
-#endif
     GET_INST_OPCODE(ip)                 @ extract opcode from rINST
     GOTO_OPCODE(ip)                     @ jump to next instruction
 
index 0cacb5d..4784fbc 100644 (file)
@@ -860,16 +860,10 @@ dalvik_inst:
     GET_VREG(r1, r2)                    @ r1<- vAA (object)
     ldr     r0, [rGLUE, #offGlue_self]  @ r0<- glue->self
     cmp     r1, #0                      @ null object?
-    EXPORT_PC()                         @ need for precise GC, MONITOR_TRACKING
+    EXPORT_PC()                         @ need for precise GC
     beq     common_errNullObject        @ null object, throw an exception
     FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
     bl      dvmLockObject               @ call(self, obj)
-#ifdef WITH_DEADLOCK_PREDICTION /* implies WITH_MONITOR_TRACKING */
-    ldr     r0, [rGLUE, #offGlue_self]  @ r0<- glue->self
-    ldr     r1, [r0, #offThread_exception] @ check for exception
-    cmp     r1, #0
-    bne     common_exceptionThrown      @ exception raised, bail out
-#endif
     GET_INST_OPCODE(ip)                 @ extract opcode from rINST
     GOTO_OPCODE(ip)                     @ jump to next instruction
 
index 2ab215e..8d5786c 100644 (file)
@@ -860,16 +860,10 @@ dalvik_inst:
     GET_VREG(r1, r2)                    @ r1<- vAA (object)
     ldr     r0, [rGLUE, #offGlue_self]  @ r0<- glue->self
     cmp     r1, #0                      @ null object?
-    EXPORT_PC()                         @ need for precise GC, MONITOR_TRACKING
+    EXPORT_PC()                         @ need for precise GC
     beq     common_errNullObject        @ null object, throw an exception
     FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
     bl      dvmLockObject               @ call(self, obj)
-#ifdef WITH_DEADLOCK_PREDICTION /* implies WITH_MONITOR_TRACKING */
-    ldr     r0, [rGLUE, #offGlue_self]  @ r0<- glue->self
-    ldr     r1, [r0, #offThread_exception] @ check for exception
-    cmp     r1, #0
-    bne     common_exceptionThrown      @ exception raised, bail out
-#endif
     GET_INST_OPCODE(ip)                 @ extract opcode from rINST
     GOTO_OPCODE(ip)                     @ jump to next instruction
 
index 8a3e43b..2ba7e5a 100644 (file)
@@ -1845,9 +1845,7 @@ dalvik_inst:
     GET_VREG    rINST                   # rINST<- vAA
     cmp         $0, rINST              # check for null object
     movl        offGlue_self(%eax), %eax # %eax<- glue->self
-#ifdef WITH_MONITOR_TRACKING
-    EXPORT_PC   # export PC so we can grab stack trace
-#endif
+    EXPORT_PC   # need for precise GC
     je          common_errNullObject    # handle null object
 #    jmp         .LOP_MONITOR_ENTER_finish
 #%break
@@ -1860,13 +1858,6 @@ dalvik_inst:
                                         # return: void
     FFETCH_ADV  1, %edx                 # %edx<- next instruction hi; fetch, advance
     lea         8(%esp), %esp
-#ifdef WITH_DEADLOCK_PREDICTION
-    movl        rGLUE, %eax             # %eax<- pMterpGlue
-    movl        offGlue_self(%eax), %eax # %eax<- glue->self
-    movl        offThread_exception(%eax), %eax # %eax<- glue->self->exception
-    cmp         $0, %eax               # check for exception
-    jne         common_exceptionThrown  # handle exception
-#endif
     FGETOP_JMP  1, %edx                 # jump to next instruction; getop, jmp
 
 /* ------------------------------ */
index 7e62798..e42a8cd 100644 (file)
@@ -1059,7 +1059,7 @@ dvmAsmInstructionStart = .L_OP_NOP
     movl    offGlue_self(%ecx),%ecx     # ecx<- glue->self
     FETCH_INST_WORD 1
     testl   %eax,%eax                   # null object?
-    EXPORT_PC                           # need for precise GC, MONITOR_TRACKING
+    EXPORT_PC                           # need for precise GC
     jne     .LOP_MONITOR_ENTER_continue
     jmp     common_errNullObject
 
@@ -9261,13 +9261,6 @@ dvmAsmSisterStart:
     movl    %ecx,OUT_ARG0(%esp)
     movl    %eax,OUT_ARG1(%esp)
     call    dvmLockObject               # dvmLockObject(self,object)
-#ifdef WITH_DEADLOCK_PREDICTION
-    movl    rGLUE,%ecx
-    movl    offGlueSelf(%ecx),%ecx      # ecx<- glue->self
-    movl    offThread_exception(%ecx),%eax
-    testl   %eax,%eax
-    jne     common_exceptionThrown
-#endif
     ADVANCE_PC 1
     GOTO_NEXT
 
index 861a150..e1acf61 100644 (file)
@@ -1653,12 +1653,8 @@ HANDLE_OPCODE(OP_MONITOR_ENTER /*vAA*/)
         if (!checkForNullExportPC(obj, fp, pc))
             GOTO_exceptionThrown();
         ILOGV("+ locking %p %s\n", obj, obj->clazz->descriptor);
-        EXPORT_PC();    /* need for precise GC, also WITH_MONITOR_TRACKING */
+        EXPORT_PC();    /* need for precise GC */
         dvmLockObject(self, obj);
-#ifdef WITH_DEADLOCK_PREDICTION
-        if (dvmCheckException(self))
-            GOTO_exceptionThrown();
-#endif
     }
     FINISH(1);
 OP_END
index 00caa6e..94f927c 100644 (file)
@@ -2015,12 +2015,8 @@ HANDLE_OPCODE(OP_MONITOR_ENTER /*vAA*/)
         if (!checkForNullExportPC(obj, fp, pc))
             GOTO_exceptionThrown();
         ILOGV("+ locking %p %s\n", obj, obj->clazz->descriptor);
-        EXPORT_PC();    /* need for precise GC, also WITH_MONITOR_TRACKING */
+        EXPORT_PC();    /* need for precise GC */
         dvmLockObject(self, obj);
-#ifdef WITH_DEADLOCK_PREDICTION
-        if (dvmCheckException(self))
-            GOTO_exceptionThrown();
-#endif
     }
     FINISH(1);
 OP_END
index 46b712f..dbcf913 100644 (file)
@@ -1765,12 +1765,8 @@ HANDLE_OPCODE(OP_MONITOR_ENTER /*vAA*/)
         if (!checkForNullExportPC(obj, fp, pc))
             GOTO_exceptionThrown();
         ILOGV("+ locking %p %s\n", obj, obj->clazz->descriptor);
-        EXPORT_PC();    /* need for precise GC, also WITH_MONITOR_TRACKING */
+        EXPORT_PC();    /* need for precise GC */
         dvmLockObject(self, obj);
-#ifdef WITH_DEADLOCK_PREDICTION
-        if (dvmCheckException(self))
-            GOTO_exceptionThrown();
-#endif
     }
     FINISH(1);
 OP_END
index d3fada3..39d0e7b 100644 (file)
@@ -33,9 +33,7 @@
     GET_VREG    rINST                   # rINST<- vAA
     cmp         $$0, rINST              # check for null object
     movl        offGlue_self(%eax), %eax # %eax<- glue->self
-#ifdef WITH_MONITOR_TRACKING
-    EXPORT_PC   # export PC so we can grab stack trace
-#endif
+    EXPORT_PC   # need for precise GC
     je          common_errNullObject    # handle null object
 #    jmp         .L${opcode}_finish
 #%break
                                         # return: void
     FFETCH_ADV  1, %edx                 # %edx<- next instruction hi; fetch, advance
     lea         8(%esp), %esp
-#ifdef WITH_DEADLOCK_PREDICTION
-    movl        rGLUE, %eax             # %eax<- pMterpGlue
-    movl        offGlue_self(%eax), %eax # %eax<- glue->self
-    movl        offThread_exception(%eax), %eax # %eax<- glue->self->exception
-    cmp         $$0, %eax               # check for exception
-    jne         common_exceptionThrown  # handle exception
-#endif
     FGETOP_JMP  1, %edx                 # jump to next instruction; getop, jmp
index 848f0fd..a267266 100644 (file)
@@ -9,7 +9,7 @@
     movl    offGlue_self(%ecx),%ecx     # ecx<- glue->self
     FETCH_INST_WORD 1
     testl   %eax,%eax                   # null object?
-    EXPORT_PC                           # need for precise GC, MONITOR_TRACKING
+    EXPORT_PC                           # need for precise GC
     jne     .L${opcode}_continue
     jmp     common_errNullObject
 %break
     movl    %ecx,OUT_ARG0(%esp)
     movl    %eax,OUT_ARG1(%esp)
     call    dvmLockObject               # dvmLockObject(self,object)
-#ifdef WITH_DEADLOCK_PREDICTION
-    movl    rGLUE,%ecx
-    movl    offGlueSelf(%ecx),%ecx      # ecx<- glue->self
-    movl    offThread_exception(%ecx),%eax
-    testl   %eax,%eax
-    jne     common_exceptionThrown
-#endif
     ADVANCE_PC 1
     GOTO_NEXT