summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorElliott Hughes <enh@google.com>2012-12-06 16:33:38 -0800
committerElliott Hughes <enh@google.com>2012-12-06 16:33:38 -0800
commit333155b24b606fa90e7fcd54c90bd5186d24a937 (patch)
tree5ba991fd8c67db9fd2d481a2e9a53b8d359de45d
parentc2228b7feb1ed2b143666ae1a664c1cc4188ec48 (diff)
downloadandroid_dalvik-333155b24b606fa90e7fcd54c90bd5186d24a937.tar.gz
android_dalvik-333155b24b606fa90e7fcd54c90bd5186d24a937.tar.bz2
android_dalvik-333155b24b606fa90e7fcd54c90bd5186d24a937.zip
Don't cache failures in the interface cache.
If we try to reuse a failure, we'll be holding a NULL Method* without the current thread having the appropriate exception pending, which will lead to a SIGSEGV. I've added a corresponding vm-test to cts/. Bug: http://code.google.com/p/android/issues/detail?id=29358 Change-Id: I044e438c46fce256c8eff2dac5d86778734d5614
-rw-r--r--vm/AtomicCache.h6
-rw-r--r--vm/mterp/common/FindInterface.h1
-rw-r--r--vm/oo/TypeCheck.cpp1
3 files changed, 6 insertions, 2 deletions
diff --git a/vm/AtomicCache.h b/vm/AtomicCache.h
index 00a0900d9..42ba6bede 100644
--- a/vm/AtomicCache.h
+++ b/vm/AtomicCache.h
@@ -136,8 +136,10 @@ struct AtomicCache {
* boost. \
*/ \
value = (u4) ATOMIC_CACHE_CALC; \
- dvmUpdateAtomicCache((u4) (_key1), (u4) (_key2), value, pEntry, \
- firstVersion CACHE_XARG(_cache) ); \
+ if (value == 0 && ATOMIC_CACHE_NULL_ALLOWED) { \
+ dvmUpdateAtomicCache((u4) (_key1), (u4) (_key2), value, pEntry, \
+ firstVersion CACHE_XARG(_cache) ); \
+ } \
} \
value; \
})
diff --git a/vm/mterp/common/FindInterface.h b/vm/mterp/common/FindInterface.h
index 72d45ff02..23e6f0e92 100644
--- a/vm/mterp/common/FindInterface.h
+++ b/vm/mterp/common/FindInterface.h
@@ -31,6 +31,7 @@ INLINE Method* dvmFindInterfaceMethodInCache(ClassObject* thisClass,
{
#define ATOMIC_CACHE_CALC \
dvmInterpFindInterfaceMethod(thisClass, methodIdx, method, methodClassDex)
+#define ATOMIC_CACHE_NULL_ALLOWED false
return (Method*) ATOMIC_CACHE_LOOKUP(methodClassDex->pInterfaceCache,
DEX_INTERFACE_CACHE_SIZE, thisClass, methodIdx);
diff --git a/vm/oo/TypeCheck.cpp b/vm/oo/TypeCheck.cpp
index 1116d1555..5228512c1 100644
--- a/vm/oo/TypeCheck.cpp
+++ b/vm/oo/TypeCheck.cpp
@@ -242,6 +242,7 @@ int dvmInstanceofNonTrivial(const ClassObject* instance,
const ClassObject* clazz)
{
#define ATOMIC_CACHE_CALC isInstanceof(instance, clazz)
+#define ATOMIC_CACHE_NULL_ALLOWED true
return ATOMIC_CACHE_LOOKUP(gDvm.instanceofCache,
INSTANCEOF_CACHE_SIZE, instance, clazz);
#undef ATOMIC_CACHE_CALC