Fix locking on string init map (again).

Follow-up to
    https://android-review.googlesource.com/172036 ,
    https://android-review.googlesource.com/171621 .

Don't overwrite existing values, only insert new ones.
(Also improve performance by using move semantics.)

This prevents the following race: Thread 1 looks for string
init map for a method but doesn't find it, so it starts to
construct a new map. Thread 2 is doing the same but it's
faster and actually inserts the new map and keeps a pointer
to it. After Thread 2 releases the lock, Thread 1 acquires
it and starts to Overwrite() the element that the Thread 2
is currently using, so Thread 2 ends up looking at a map
that's being actively modified.

Change-Id: I135571af644363ea7bb282969a1bc7287b34f9b2
diff --git a/runtime/interpreter/interpreter_common.cc b/runtime/interpreter/interpreter_common.cc
index 68d56f5..5fbd687 100644
--- a/runtime/interpreter/interpreter_common.cc
+++ b/runtime/interpreter/interpreter_common.cc
@@ -709,7 +709,11 @@
       SafeMap<uint32_t, std::set<uint32_t>> string_init_map =
           verifier::MethodVerifier::FindStringInitMap(method);
       MutexLock mu(self, *Locks::interpreter_string_init_map_lock_);
-      auto it = method_to_string_init_map.Overwrite(method_ref, string_init_map);
+      auto it = method_to_string_init_map.lower_bound(method_ref);
+      if (it == method_to_string_init_map.end() ||
+          method_to_string_init_map.key_comp()(method_ref, it->first)) {
+        it = method_to_string_init_map.PutBefore(it, method_ref, std::move(string_init_map));
+      }
       string_init_map_ptr = &it->second;
     }
     if (string_init_map_ptr->size() != 0) {