Code drop from //branches/cupcake/...@124589
diff --git a/libs/utils/Android.mk b/libs/utils/Android.mk
index 4a68dc1..cdb8ca2 100644
--- a/libs/utils/Android.mk
+++ b/libs/utils/Android.mk
@@ -139,6 +139,14 @@
 	liblog \
 	libcutils
 
+ifneq ($(TARGET_SIMULATOR),true)
+ifeq ($(TARGET_OS)-$(TARGET_ARCH),linux-x86)
+# This is needed on x86 to bring in dl_iterate_phdr for CallStack.cpp
+LOCAL_SHARED_LIBRARIES += \
+	libdl
+endif # linux-x86
+endif # sim
+
 LOCAL_MODULE:= libutils
 
 #LOCAL_CFLAGS+=
diff --git a/libs/utils/CallStack.cpp b/libs/utils/CallStack.cpp
index 4968666..26fb22a 100644
--- a/libs/utils/CallStack.cpp
+++ b/libs/utils/CallStack.cpp
@@ -79,35 +79,35 @@
 /*****************************************************************************/
 
 static 
-const char *lookup_symbol(const void* addr, uint32_t *offset, char* name, size_t bufSize)
+const char *lookup_symbol(const void* addr, void **offset, char* name, size_t bufSize)
 {
 #if HAVE_DLADDR
-	Dl_info info;
-	if (dladdr(addr, &info)) {
-		*offset = (uint32_t)info.dli_saddr;
-		return info.dli_sname;
-	}
+    Dl_info info;
+    if (dladdr(addr, &info)) {
+        *offset = info.dli_saddr;
+        return info.dli_sname;
+    }
 #endif
-	return NULL;
+    return NULL;
 }
 
 static 
 int32_t linux_gcc_demangler(const char *mangled_name, char *unmangled_name, size_t buffersize)
 {
-	size_t out_len = 0;
+    size_t out_len = 0;
 #if HAVE_CXXABI
-	int status = 0;
-	char *demangled = abi::__cxa_demangle(mangled_name, 0, &out_len, &status);
-	if (status == 0) {
-		// OK
-		if (out_len < buffersize) memcpy(unmangled_name, demangled, out_len);
-		else out_len = 0;
-		free(demangled);
-	} else {
-		out_len = 0;
-	}
+    int status = 0;
+    char *demangled = abi::__cxa_demangle(mangled_name, 0, &out_len, &status);
+    if (status == 0) {
+        // OK
+        if (out_len < buffersize) memcpy(unmangled_name, demangled, out_len);
+        else out_len = 0;
+        free(demangled);
+    } else {
+        out_len = 0;
+    }
 #endif
-	return out_len;
+    return out_len;
 }
 
 /*****************************************************************************/
@@ -115,12 +115,12 @@
 class MapInfo {
     struct mapinfo {
         struct mapinfo *next;
-        unsigned start;
-        unsigned end;
+        uint64_t start;
+        uint64_t end;
         char name[];
     };
 
-    const char *map_to_name(unsigned pc, const char* def) {
+    const char *map_to_name(uint64_t pc, const char* def) {
         mapinfo* mi = getMapInfoList();
         while(mi) {
             if ((pc >= mi->start) && (pc < mi->end))
@@ -139,8 +139,8 @@
         if (line[20] != 'x') return 0;
         mi = (mapinfo*)malloc(sizeof(mapinfo) + (len - 47));
         if (mi == 0) return 0;
-        mi->start = strtoul(line, 0, 16);
-        mi->end = strtoul(line + 9, 0, 16);
+        mi->start = strtoull(line, 0, 16);
+        mi->end = strtoull(line + 9, 0, 16);
         mi->next = 0;
         strcpy(mi->name, line + 49);
         return mi;
@@ -184,7 +184,7 @@
     }
     
     static const char *mapAddressToName(const void* pc, const char* def) {
-        return sMapInfo.map_to_name((unsigned)pc, def);
+        return sMapInfo.map_to_name((uint64_t)pc, def);
     }
 
 };
@@ -278,7 +278,7 @@
     char tmp[256];
     char tmp1[32];
     char tmp2[32];
-    uint32_t offs;
+    void *offs;
 
     const void* ip = mStack[level];
     if (!ip) return res;
@@ -291,14 +291,14 @@
     if (name) {
         if (linux_gcc_demangler(name, tmp, 256) != 0)
             name = tmp;
-        snprintf(tmp1, 32, "0x%08x: <", (size_t)ip);
-        snprintf(tmp2, 32, ">+0x%08x", offs);
+        snprintf(tmp1, 32, "0x%p: <", ip);
+        snprintf(tmp2, 32, ">+0x%p", offs);
         res.append(tmp1);
         res.append(name);
         res.append(tmp2);
     } else { 
         name = MapInfo::mapAddressToName(ip, "<unknown>");
-        snprintf(tmp, 256, "pc %08x  %s", (size_t)ip, name);
+        snprintf(tmp, 256, "pc %p  %s", ip, name);
         res.append(tmp);
     }
     res.append("\n");
diff --git a/libs/utils/IPCThreadState.cpp b/libs/utils/IPCThreadState.cpp
index ca49d9a..04ae142 100644
--- a/libs/utils/IPCThreadState.cpp
+++ b/libs/utils/IPCThreadState.cpp
@@ -391,6 +391,29 @@
     status_t result;
     do {
         int32_t cmd;
+        
+        // When we've cleared the incoming command queue, process any pending derefs
+        if (mIn.dataPosition() >= mIn.dataSize()) {
+            size_t numPending = mPendingWeakDerefs.size();
+            if (numPending > 0) {
+                for (size_t i = 0; i < numPending; i++) {
+                    RefBase::weakref_type* refs = mPendingWeakDerefs[i];
+                    refs->decWeak(mProcess.get());
+                }
+                mPendingWeakDerefs.clear();
+            }
+
+            numPending = mPendingStrongDerefs.size();
+            if (numPending > 0) {
+                for (size_t i = 0; i < numPending; i++) {
+                    BBinder* obj = mPendingStrongDerefs[i];
+                    obj->decStrong(mProcess.get());
+                }
+                mPendingStrongDerefs.clear();
+            }
+        }
+
+        // now get the next command to be processed, waiting if necessary
         result = talkWithDriver();
         if (result >= NO_ERROR) {
             size_t IN = mIn.dataAvail();
@@ -832,7 +855,7 @@
             LOG_REMOTEREFS("BR_RELEASE from driver on %p", obj);
             obj->printRefs();
         }
-        obj->decStrong(mProcess.get());
+        mPendingStrongDerefs.push(obj);
         break;
         
     case BR_INCREFS:
@@ -853,7 +876,7 @@
         //LOG_ASSERT(refs->refBase() == obj,
         //           "BR_DECREFS: object %p does not match cookie %p (expected %p)",
         //           refs, obj, refs->refBase());
-        refs->decWeak(mProcess.get());
+        mPendingWeakDerefs.push(refs);
         break;
         
     case BR_ATTEMPT_ACQUIRE:
diff --git a/libs/utils/LogSocket.cpp b/libs/utils/LogSocket.cpp
index e64f794..55c1b99 100644
--- a/libs/utils/LogSocket.cpp
+++ b/libs/utils/LogSocket.cpp
@@ -16,7 +16,7 @@
 
 
 #ifndef HAVE_WINSOCK
-#define SOCKETLOG
+//#define SOCKETLOG
 #endif
 
 #ifdef SOCKETLOG
diff --git a/libs/utils/MemoryDealer.cpp b/libs/utils/MemoryDealer.cpp
index e6d1d18..cf8201b 100644
--- a/libs/utils/MemoryDealer.cpp
+++ b/libs/utils/MemoryDealer.cpp
@@ -387,21 +387,23 @@
     start = (start + pagesize-1) & ~(pagesize-1);
     end &= ~(pagesize-1);    
 
-    void* const start_ptr = (void*)(intptr_t(getHeap()->base()) + start);
-    size_t size = end-start;
+    if (start < end) {
+        void* const start_ptr = (void*)(intptr_t(getHeap()->base()) + start);
+        size_t size = end-start;
 
 #ifndef NDEBUG
-    memset(start_ptr, 0xdf, size);
+        memset(start_ptr, 0xdf, size);
 #endif
-  
-// MADV_REMOVE is not defined on Dapper based Goobuntu 
+
+        // MADV_REMOVE is not defined on Dapper based Goobuntu 
 #ifdef MADV_REMOVE 
-    if (size) {
-        int err = madvise(start_ptr, size, MADV_REMOVE);
-        LOGW_IF(err, "madvise(%p, %u, MADV_REMOVE) returned %s",
-                start_ptr, size, err<0 ? strerror(errno) : "Ok");
-    }
+        if (size) {
+            int err = madvise(start_ptr, size, MADV_REMOVE);
+            LOGW_IF(err, "madvise(%p, %u, MADV_REMOVE) returned %s",
+                    start_ptr, size, err<0 ? strerror(errno) : "Ok");
+        }
 #endif
+    }
 }
 
 }; // namespace android
diff --git a/libs/utils/MemoryHeapPmem.cpp b/libs/utils/MemoryHeapPmem.cpp
index 1e5a1cc..eba2b30 100644
--- a/libs/utils/MemoryHeapPmem.cpp
+++ b/libs/utils/MemoryHeapPmem.cpp
@@ -38,9 +38,20 @@
 
 // ---------------------------------------------------------------------------
 
-class MemoryHeapPmem;
+MemoryHeapPmem::MemoryPmem::MemoryPmem(const sp<MemoryHeapPmem>& heap)
+    : BnMemory(), mClientHeap(heap)
+{
+}
 
-class SubRegionMemory : public BnMemory {
+MemoryHeapPmem::MemoryPmem::~MemoryPmem() {
+    if (mClientHeap != NULL) {
+        mClientHeap->remove(this);
+    }
+}
+
+// ---------------------------------------------------------------------------
+
+class SubRegionMemory : public MemoryHeapPmem::MemoryPmem {
 public:
     SubRegionMemory(const sp<MemoryHeapPmem>& heap, ssize_t offset, size_t size);
     virtual ~SubRegionMemory();
@@ -50,15 +61,14 @@
     void revoke();
     size_t              mSize;
     ssize_t             mOffset;
-    sp<MemoryHeapPmem>  mClientHeap;
 };
 
 SubRegionMemory::SubRegionMemory(const sp<MemoryHeapPmem>& heap,
         ssize_t offset, size_t size)
-    : mSize(size), mOffset(offset), mClientHeap(heap)
+    : MemoryHeapPmem::MemoryPmem(heap), mSize(size), mOffset(offset)
 {
 #ifndef NDEBUG
-    void* const start_ptr = (void*)(intptr_t(mClientHeap->base()) + offset);
+    void* const start_ptr = (void*)(intptr_t(getHeap()->base()) + offset);
     memset(start_ptr, 0xda, size);
 #endif
 
@@ -80,7 +90,7 @@
 {
     if (offset) *offset = mOffset;
     if (size)   *size = mSize;
-    return mClientHeap;
+    return getHeap();
 }
 
 SubRegionMemory::~SubRegionMemory()
@@ -98,8 +108,9 @@
     // promote() it.
     
 #if HAVE_ANDROID_OS
-    if (mClientHeap != NULL) {
-        int our_fd = mClientHeap->heapID();
+    if (mSize != NULL) {
+        const sp<MemoryHeapPmem>& heap(getHeap());
+        int our_fd = heap->heapID();
         struct pmem_region sub;
         sub.offset = mOffset;
         sub.len = mSize;
@@ -107,7 +118,7 @@
         LOGE_IF(err<0, "PMEM_UNMAP failed (%s), "
                 "mFD=%d, sub.offset=%lu, sub.size=%lu",
                 strerror(errno), our_fd, sub.offset, sub.len);
-        mClientHeap.clear();
+        mSize = 0;
     }
 #endif
 }
@@ -157,10 +168,7 @@
 
 sp<IMemory> MemoryHeapPmem::mapMemory(size_t offset, size_t size)
 {
-    sp<SubRegionMemory> memory;
-    if (heapID() > 0) 
-        memory = new SubRegionMemory(this, offset, size);
-
+    sp<MemoryPmem> memory = createMemory(offset, size);
     if (memory != 0) {
         Mutex::Autolock _l(mLock);
         mAllocations.add(memory);
@@ -168,6 +176,15 @@
     return memory;
 }
 
+sp<MemoryHeapPmem::MemoryPmem> MemoryHeapPmem::createMemory(
+        size_t offset, size_t size)
+{
+    sp<SubRegionMemory> memory;
+    if (heapID() > 0) 
+        memory = new SubRegionMemory(this, offset, size);
+    return memory;
+}
+
 status_t MemoryHeapPmem::slap()
 {
 #if HAVE_ANDROID_OS
@@ -206,21 +223,26 @@
 
 void MemoryHeapPmem::revoke()
 {
-    Vector< wp<SubRegionMemory> > allocations;
+    SortedVector< wp<MemoryPmem> > allocations;
 
     { // scope for lock
         Mutex::Autolock _l(mLock);
         allocations = mAllocations;
-        mAllocations.clear();
     }
     
     ssize_t count = allocations.size();
     for (ssize_t i=0 ; i<count ; i++) {
-        sp<SubRegionMemory> memory(allocations[i].promote());
+        sp<MemoryPmem> memory(allocations[i].promote());
         if (memory != 0)
             memory->revoke();
     }
 }
 
+void MemoryHeapPmem::remove(const wp<MemoryPmem>& memory)
+{
+    Mutex::Autolock _l(mLock);
+    mAllocations.remove(memory);
+}
+
 // ---------------------------------------------------------------------------
 }; // namespace android
diff --git a/libs/utils/ResourceTypes.cpp b/libs/utils/ResourceTypes.cpp
index a5fe9fb..5a09fb4 100644
--- a/libs/utils/ResourceTypes.cpp
+++ b/libs/utils/ResourceTypes.cpp
@@ -164,7 +164,11 @@
 
 size_t Res_png_9patch::serializedSize()
 {
-    return sizeof(Res_png_9patch)
+    // The size of this struct is 32 bytes on the 32-bit target system
+    // 4 * int8_t
+    // 4 * int32_t
+    // 3 * pointer
+    return 32
             + numXDivs * sizeof(int32_t)
             + numYDivs * sizeof(int32_t)
             + numColors * sizeof(uint32_t);
@@ -180,8 +184,10 @@
 void Res_png_9patch::serialize(void * outData)
 {
     char* data = (char*) outData;
-    memmove(data, this, sizeof(Res_png_9patch));
-    data +=  sizeof(Res_png_9patch);
+    memmove(data, &wasDeserialized, 4);     // copy  wasDeserialized, numXDivs, numYDivs, numColors
+    memmove(data + 12, &paddingLeft, 16);   // copy paddingXXXX
+    data += 32;
+
     memmove(data, this->xDivs, numXDivs * sizeof(int32_t));
     data +=  numXDivs * sizeof(int32_t);
     memmove(data, this->yDivs, numYDivs * sizeof(int32_t));
@@ -189,27 +195,32 @@
     memmove(data, this->colors, numColors * sizeof(uint32_t));
 }
 
-Res_png_9patch* Res_png_9patch::deserialize(const void* inData)
-{
-    deserialize(inData, (Res_png_9patch*) inData);
-    return (Res_png_9patch*) inData;
-}
-
-void Res_png_9patch::deserialize(const void* inData, Res_png_9patch* outData) {
-    Res_png_9patch* patch = (Res_png_9patch*) inData;
+static void deserializeInternal(const void* inData, Res_png_9patch* outData) {
+    char* patch = (char*) inData;
     if (inData != outData) {
-        memcpy(outData, inData, patch->serializedSize());
+        memmove(&outData->wasDeserialized, patch, 4);     // copy  wasDeserialized, numXDivs, numYDivs, numColors
+        memmove(&outData->paddingLeft, patch + 12, 4);     // copy  wasDeserialized, numXDivs, numYDivs, numColors
     }
     outData->wasDeserialized = true;
     char* data = (char*)outData;
     data +=  sizeof(Res_png_9patch);
     outData->xDivs = (int32_t*) data;
-    data +=  patch->numXDivs * sizeof(int32_t);
+    data +=  outData->numXDivs * sizeof(int32_t);
     outData->yDivs = (int32_t*) data;
-    data +=  patch->numYDivs * sizeof(int32_t);
+    data +=  outData->numYDivs * sizeof(int32_t);
     outData->colors = (uint32_t*) data;
 }
 
+Res_png_9patch* Res_png_9patch::deserialize(const void* inData)
+{
+    if (sizeof(void*) != sizeof(int32_t)) {
+        LOGE("Cannot deserialize on non 32-bit system\n");
+        return NULL;
+    }
+    deserializeInternal(inData, (Res_png_9patch*) inData);
+    return (Res_png_9patch*) inData;
+}
+
 // --------------------------------------------------------------------
 // --------------------------------------------------------------------
 // --------------------------------------------------------------------
@@ -3863,7 +3874,7 @@
                 }
                 for (size_t configIndex=0; configIndex<NTC; configIndex++) {
                     const ResTable_type* type = typeConfigs->configs[configIndex];
-                    if ((((int)type)&0x3) != 0) {
+                    if ((((uint64_t)type)&0x3) != 0) {
                         printf("      NON-INTEGER ResTable_type ADDRESS: %p\n", type);
                         continue;
                     }
diff --git a/libs/utils/futex_synchro.c b/libs/utils/futex_synchro.c
index c13760d..ba19520 100644
--- a/libs/utils/futex_synchro.c
+++ b/libs/utils/futex_synchro.c
@@ -25,8 +25,8 @@
 #include <private/utils/futex_synchro.h>
 
 
-// This futex glue code is need on desktop linux, but is part of klibc on ARM
-#if !defined(__arm__)
+// This futex glue code is need on desktop linux, but is already part of bionic.
+#if !defined(HAVE_FUTEX_WRAPPERS)
 
 #include <sys/syscall.h>
 typedef unsigned int u32;
@@ -76,7 +76,7 @@
 int __atomic_swap(int _new, volatile int *ptr);
 int __atomic_dec(volatile int *ptr);
 
-#endif // !defined(__arm__)
+#endif // !defined(HAVE_FUTEX_WRAPPERS)
 
 
 // lock states