/*
* Who last acquired this monitor, when lock sampling is enabled.
- * Even when enabled, ownerFileName may be NULL.
+ * Even when enabled, ownerMethod may be NULL.
*/
- const char* ownerFileName;
- u4 ownerLineNumber;
+ const Method* ownerMethod;
+ u4 ownerPc;
};
mon = (Monitor*) calloc(1, sizeof(Monitor));
if (mon == NULL) {
- LOGE("Unable to allocate monitor");
- dvmAbort();
- }
- if (((u4)mon & 7) != 0) {
- LOGE("Misaligned monitor: %p", mon);
+ ALOGE("Unable to allocate monitor");
dvmAbort();
}
mon->obj = obj;
size_t len;
int fd;
+ /* When a thread is being destroyed it is normal that the frame depth is zero */
+ if (self->interpSave.curFrame == NULL) {
+ return;
+ }
+
saveArea = SAVEAREA_FROM_FP(self->interpSave.curFrame);
meth = saveArea->method;
cp = eventBuffer;
if (waitThreshold) {
waitStart = dvmGetRelativeTimeUsec();
}
- const char* currentOwnerFileName = mon->ownerFileName;
- u4 currentOwnerLineNumber = mon->ownerLineNumber;
+
+ const Method* currentOwnerMethod = mon->ownerMethod;
+ u4 currentOwnerPc = mon->ownerPc;
dvmLockMutex(&mon->lock);
if (waitThreshold) {
samplePercent = 100 * waitMs / waitThreshold;
}
if (samplePercent != 0 && ((u4)rand() % 100 < samplePercent)) {
+ const char* currentOwnerFileName = "no_method";
+ u4 currentOwnerLineNumber = 0;
+ if (currentOwnerMethod != NULL) {
+ currentOwnerFileName = dvmGetMethodSourceFile(currentOwnerMethod);
+ if (currentOwnerFileName == NULL) {
+ currentOwnerFileName = "no_method_file";
+ }
+ currentOwnerLineNumber = dvmLineNumFromPC(currentOwnerMethod, currentOwnerPc);
+ }
logContentionEvent(self, waitMs, samplePercent,
currentOwnerFileName, currentOwnerLineNumber);
}
// When debugging, save the current monitor holder for future
// acquisition failures to use in sampled logging.
if (gDvm.lockProfThreshold > 0) {
- const StackSaveArea *saveArea;
- const Method *meth;
- mon->ownerLineNumber = 0;
+ mon->ownerMethod = NULL;
+ mon->ownerPc = 0;
if (self->interpSave.curFrame == NULL) {
- mon->ownerFileName = "no_frame";
- } else if ((saveArea =
- SAVEAREA_FROM_FP(self->interpSave.curFrame)) == NULL) {
- mon->ownerFileName = "no_save_area";
- } else if ((meth = saveArea->method) == NULL) {
- mon->ownerFileName = "no_method";
- } else {
- u4 relativePc = saveArea->xtra.currentPc - saveArea->method->insns;
- mon->ownerFileName = (char*) dvmGetMethodSourceFile(meth);
- if (mon->ownerFileName == NULL) {
- mon->ownerFileName = "no_method_file";
- } else {
- mon->ownerLineNumber = dvmLineNumFromPC(meth, relativePc);
- }
+ return;
+ }
+ const StackSaveArea* saveArea = SAVEAREA_FROM_FP(self->interpSave.curFrame);
+ if (saveArea == NULL) {
+ return;
}
+ mon->ownerMethod = saveArea->method;
+ mon->ownerPc = (saveArea->xtra.currentPc - saveArea->method->insns);
}
}
*/
if (mon->lockCount == 0) {
mon->owner = NULL;
- mon->ownerFileName = "unlocked";
- mon->ownerLineNumber = 0;
+ mon->ownerMethod = NULL;
+ mon->ownerPc = 0;
dvmUnlockMutex(&mon->lock);
} else {
mon->lockCount--;
bool wasInterrupted = false;
bool timed;
int ret;
- const char *savedFileName;
- u4 savedLineNumber;
assert(self != NULL);
assert(mon != NULL);
int prevLockCount = mon->lockCount;
mon->lockCount = 0;
mon->owner = NULL;
- savedFileName = mon->ownerFileName;
- mon->ownerFileName = NULL;
- savedLineNumber = mon->ownerLineNumber;
- mon->ownerLineNumber = 0;
+
+ const Method* savedMethod = mon->ownerMethod;
+ u4 savedPc = mon->ownerPc;
+ mon->ownerMethod = NULL;
+ mon->ownerPc = 0;
/*
* Update thread status. If the GC wakes up, it'll ignore us, knowing
*/
mon->owner = self;
mon->lockCount = prevLockCount;
- mon->ownerFileName = savedFileName;
- mon->ownerLineNumber = savedLineNumber;
+ mon->ownerMethod = savedMethod;
+ mon->ownerPc = savedPc;
waitSetRemove(mon, self);
/* set self->status back to THREAD_RUNNING, and self-suspend if needed */
#ifndef WITH_COPYING_GC
u4 dvmIdentityHashCode(Object *obj)
{
- return (u4)obj;
+ /*
+ * The following assumes that objects are allocated at even boundaries, so
+ * the shift preserves uniqueness of hashCode() while guaranteeing a
+ * non-negative result (for the convenience of some applications,like MiTalk).
+ */
+ return (u4)(((u4)obj)>>1);
}
#else
/*
dvmUnlockThreadList();
goto retry;
}
- LOGE("object %p has an unknown hash state %#x", obj, hashState);
+ ALOGE("object %p has an unknown hash state %#x", obj, hashState);
dvmDumpThread(dvmThreadSelf(), false);
dvmAbort();
return 0; /* Quiet the compiler. */