Fix race condition in RMU
Fix race condition in RMU

Summary:
The conditional marking logic had a race condition that could result in reachable methods not being marked. Roughly, the relevant logic was as follows:

```
void push_cond(const DexMethod* method) {
  ...
  auto clazz = type_class(method->get_class());
  if (m_reachable_objects->marked(clazz)) {
    push(clazz, method);
  } else { // Point A
    m_cond_marked->methods.insert(method);
  }
}

void visit(DexClass*) {
  ...
  for (auto const& m : cls->get_dmethods()) {
    if (m_cond_marked->methods.count(m)) {
     push(cls, m);
    }
  }
  ...
}
```

Suppose thread 1 executes `push_cond`, sees that `clazz` isn't marked, jumps to `Point A` and gets suspended there by the scheduler. Meanwhile thread 2 finds a reference to that same `clazz`, marks it and pushes it onto the queue, and then eventually pops it off and runs `visit()` on it. `visit` is responsible for turning the conditionally-marked methods into fully-marked ones. Suppose thread 2 finishes running `visit` before thread 1 gets resumed. In that case, thread 1 would add a method to `m_cond_marked` that should rightfully be promoted to a fully-marked one, but that will never happen since `visit` has finished.

In practice I think this is pretty unlikely because between the marking of a class and `visit`-ing it, all the other items currently in the queue need to be handled first. So thread 1 would have to be suspended at Point A for a pretty long time for that to happen. I didn't actually observe this bug happening, I just realized it was possible after thinking about the code...

Reviewed By: minjang

Differential Revision: D9698841

fbshipit-source-id: f1e5df11cedacdccdffef39b55f7ccbae9416801

facebook/redex,facebook/redex,facebook/redex,facebook/redex,facebook/redex,facebook/redex,facebook/redex,facebook/redex,facebook/redex