OSDN Git Service

Fix very rare bug around JIT code cache collection.
authorNicolas Geoffray <ngeoffray@google.com>
Fri, 4 Mar 2016 14:32:59 +0000 (14:32 +0000)
committerNicolas Geoffray <ngeoffray@google.com>
Fri, 4 Mar 2016 15:15:28 +0000 (15:15 +0000)
commit9abb2978f09643227664ab70c0677744b8f6e946
tree69b4bb602fa5c58d6d0eabdf5f79aee2f6a60c52
parenta3ed89f687dbaa9b5321b2d38d41b487a4208b80
Fix very rare bug around JIT code cache collection.

The bug is the following:
1) JIT thread: We start a code cache collection.
2) JIT thread: We mark all code that is in the call stack of all
   threads.
3) Mutator thread: after marking its stack, resumes and does call
   that pushes JIT compiled code to the call stack.
4) Mutator thread: deoptimizes compiled code of ArtMethod Foo,
   and therefore updates the entry point of Foo through
   JitCodeCache::InvalidateCompiledCodeFor.
   (Note that updating the entrypoint could also be done through
   instrumentation).
5) JIT thread: Call JitCodeCache::RemoveUnusedAndUnmarkedCode.
   The method used to remove entries that were not entrypoints.
   It sees the compiled code for Foo but that is not an entrypoint
   anymore, so deletes it.
6) Mutator thread problem: it now has compiled code in its call
   stack that is deleted.

If it's only one mutator thread, we only hit a DCHECK when walking
the stack, as we are now seeing an invalid pc. The deoptimization
will longjmp to the caller of that invalid entry anyway.

However, if multiple mutator threads are involved, one thread
might invalidate the compiled code while the other is still
running it. And we end up deleting code that is in the call
stack of a thread, and we will crash.

The fix is to mark entrypoints before marking call stacks,
so that anything a thread might jump to is marked and kept.

bug:27424509
bug:23128949
bug:26846185

Change-Id: I07cd08cedd96b9900629f7535e95404f622104ea
runtime/jit/jit_code_cache.cc
runtime/jit/jit_code_cache.h