diff options
author | Elliott Hughes <enh@google.com> | 2012-12-06 16:33:38 -0800 |
---|---|---|
committer | Elliott Hughes <enh@google.com> | 2012-12-06 16:33:38 -0800 |
commit | 333155b24b606fa90e7fcd54c90bd5186d24a937 (patch) | |
tree | 5ba991fd8c67db9fd2d481a2e9a53b8d359de45d | |
parent | c2228b7feb1ed2b143666ae1a664c1cc4188ec48 (diff) | |
download | android_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.h | 6 | ||||
-rw-r--r-- | vm/mterp/common/FindInterface.h | 1 | ||||
-rw-r--r-- | vm/oo/TypeCheck.cpp | 1 |
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 |