Workaround for gcc volatile struct member bug

gcc does not handle struct with volatile member assignments correctly.
See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47409

Using structure assignments for the StateAndFlag union can cause gcc
to optimise the code incorrectly. Doing the assignment using the
as_int member forces the correct behaviour.

Change-Id: I6379d36add16c321b2e4d1dcd6fd8c959f3f92d6
diff --git a/runtime/thread.cc b/runtime/thread.cc
index 297fa45..fa49faa 100644
--- a/runtime/thread.cc
+++ b/runtime/thread.cc
@@ -579,7 +579,8 @@
 }
 
 bool Thread::RequestCheckpoint(Closure* function) {
-  union StateAndFlags old_state_and_flags = state_and_flags_;
+  union StateAndFlags old_state_and_flags;
+  old_state_and_flags.as_int = state_and_flags_.as_int;
   if (old_state_and_flags.as_struct.state != kRunnable) {
     return false;  // Fail, thread is suspended and so can't run a checkpoint.
   }
@@ -591,7 +592,8 @@
   // Checkpoint function installed now install flag bit.
   // We must be runnable to request a checkpoint.
   DCHECK_EQ(old_state_and_flags.as_struct.state, kRunnable);
-  union StateAndFlags new_state_and_flags = old_state_and_flags;
+  union StateAndFlags new_state_and_flags;
+  new_state_and_flags.as_int = old_state_and_flags.as_int;
   new_state_and_flags.as_struct.flags |= kCheckpointRequest;
   int succeeded = android_atomic_cmpxchg(old_state_and_flags.as_int, new_state_and_flags.as_int,
                                          &state_and_flags_.as_int);