Add Object::Get/SetField methods for 8 and 16 bit fields.

For simplicity new methods lack support for transactions.
Those new netods are used to implement sun.misc.Unsafe.get/set
methods for 8/16 bit wide primitives. Those methods are used
by the java primitive serialization/deserialization methods.

Change-Id: Iaa133b32beac996642f691e1611536f5fd11a260
diff --git a/runtime/mirror/object-inl.h b/runtime/mirror/object-inl.h
index 7a383e4..f68a9d1 100644
--- a/runtime/mirror/object-inl.h
+++ b/runtime/mirror/object-inl.h
@@ -407,6 +407,70 @@
 }
 
 template<VerifyObjectFlags kVerifyFlags, bool kIsVolatile>
+inline int8_t Object::GetField8(MemberOffset field_offset) {
+  if (kVerifyFlags & kVerifyThis) {
+    VerifyObject(this);
+  }
+  const byte* raw_addr = reinterpret_cast<const byte*>(this) + field_offset.Int32Value();
+  const int8_t* word_addr = reinterpret_cast<const int8_t*>(raw_addr);
+  if (UNLIKELY(kIsVolatile)) {
+    return reinterpret_cast<const Atomic<int8_t>*>(word_addr)->LoadSequentiallyConsistent();
+  } else {
+    return reinterpret_cast<const Atomic<int8_t>*>(word_addr)->LoadJavaData();
+  }
+}
+
+template<bool kCheckTransaction, VerifyObjectFlags kVerifyFlags,
+    bool kIsVolatile>
+inline void Object::SetField8(MemberOffset field_offset, int8_t new_value) {
+  if (kCheckTransaction) {
+    DCHECK_EQ(false, Runtime::Current()->IsActiveTransaction());
+  }
+  if (kVerifyFlags & kVerifyThis) {
+    VerifyObject(this);
+  }
+  byte* raw_addr = reinterpret_cast<byte*>(this) + field_offset.Int32Value();
+  int8_t* word_addr = reinterpret_cast<int8_t*>(raw_addr);
+  if (kIsVolatile) {
+    reinterpret_cast<Atomic<int8_t>*>(word_addr)->StoreSequentiallyConsistent(new_value);
+  } else {
+    reinterpret_cast<Atomic<int8_t>*>(word_addr)->StoreJavaData(new_value);
+  }
+}
+
+template<VerifyObjectFlags kVerifyFlags, bool kIsVolatile>
+inline int16_t Object::GetField16(MemberOffset field_offset) {
+  if (kVerifyFlags & kVerifyThis) {
+    VerifyObject(this);
+  }
+  const byte* raw_addr = reinterpret_cast<const byte*>(this) + field_offset.Int32Value();
+  const int16_t* word_addr = reinterpret_cast<const int16_t*>(raw_addr);
+  if (UNLIKELY(kIsVolatile)) {
+    return reinterpret_cast<const Atomic<int16_t>*>(word_addr)->LoadSequentiallyConsistent();
+  } else {
+    return reinterpret_cast<const Atomic<int16_t>*>(word_addr)->LoadJavaData();
+  }
+}
+
+template<bool kCheckTransaction, VerifyObjectFlags kVerifyFlags,
+    bool kIsVolatile>
+inline void Object::SetField16(MemberOffset field_offset, int16_t new_value) {
+  if (kCheckTransaction) {
+    DCHECK_EQ(false, Runtime::Current()->IsActiveTransaction());
+  }
+  if (kVerifyFlags & kVerifyThis) {
+    VerifyObject(this);
+  }
+  byte* raw_addr = reinterpret_cast<byte*>(this) + field_offset.Int32Value();
+  int16_t* word_addr = reinterpret_cast<int16_t*>(raw_addr);
+  if (kIsVolatile) {
+    reinterpret_cast<Atomic<int16_t>*>(word_addr)->StoreSequentiallyConsistent(new_value);
+  } else {
+    reinterpret_cast<Atomic<int16_t>*>(word_addr)->StoreJavaData(new_value);
+  }
+}
+
+template<VerifyObjectFlags kVerifyFlags, bool kIsVolatile>
 inline int32_t Object::GetField32(MemberOffset field_offset) {
   if (kVerifyFlags & kVerifyThis) {
     VerifyObject(this);
diff --git a/runtime/mirror/object.h b/runtime/mirror/object.h
index bf76c86..3bc40ae 100644
--- a/runtime/mirror/object.h
+++ b/runtime/mirror/object.h
@@ -247,6 +247,24 @@
   HeapReference<Object>* GetFieldObjectReferenceAddr(MemberOffset field_offset);
 
   template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags, bool kIsVolatile = false>
+  ALWAYS_INLINE int8_t GetField8(MemberOffset field_offset)
+      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+  template<bool kCheckTransaction = true,
+      VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags, bool kIsVolatile = false>
+  ALWAYS_INLINE void SetField8(MemberOffset field_offset, int8_t new_value)
+      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+  template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags, bool kIsVolatile = false>
+  ALWAYS_INLINE int16_t GetField16(MemberOffset field_offset)
+      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+  template<bool kCheckTransaction = true,
+      VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags, bool kIsVolatile = false>
+  ALWAYS_INLINE void SetField16(MemberOffset field_offset, int16_t new_value)
+      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+  template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags, bool kIsVolatile = false>
   ALWAYS_INLINE int32_t GetField32(MemberOffset field_offset)
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
diff --git a/runtime/native/sun_misc_Unsafe.cc b/runtime/native/sun_misc_Unsafe.cc
index b431d0e..b0352ec 100644
--- a/runtime/native/sun_misc_Unsafe.cc
+++ b/runtime/native/sun_misc_Unsafe.cc
@@ -372,67 +372,55 @@
     }
 }
 static jboolean Unsafe_getBoolean(JNIEnv* env, jobject, jobject javaObj, jlong offset) {
-  // TODO(haaawk): Fix this.
-  //ScopedFastNativeObjectAccess soa(env);
-  //mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
-  //return obj->GetField8(MemberOffset(offset));
-  return 0;
+    ScopedFastNativeObjectAccess soa(env);
+    mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
+    return obj->GetField8(MemberOffset(offset));
 }
 
 static void Unsafe_putBoolean(JNIEnv* env, jobject, jobject javaObj, jlong offset, jboolean newValue) {
-  // TODO(haaawk): Fix this.
-  //ScopedFastNativeObjectAccess soa(env);
-  //mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
-  // JNI must use non transactional mode.
-  //obj->SetField8<false>(MemberOffset(offset), newValue);
+    ScopedFastNativeObjectAccess soa(env);
+    mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
+    // JNI must use non transactional mode (SetField8 is non-transactional).
+    obj->SetField8(MemberOffset(offset), newValue);
 }
 
 static jbyte Unsafe_getByte(JNIEnv* env, jobject, jobject javaObj, jlong offset) {
-  // TODO(haaawk): Fix this.
-  //ScopedFastNativeObjectAccess soa(env);
-  //mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
-  //return obj->GetField8(MemberOffset(offset));
-  return 0;
+    ScopedFastNativeObjectAccess soa(env);
+    mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
+    return obj->GetField8(MemberOffset(offset));
 }
 
 static void Unsafe_putByte(JNIEnv* env, jobject, jobject javaObj, jlong offset, jbyte newValue) {
-  // TODO(haaawk): Fix this.
-  //ScopedFastNativeObjectAccess soa(env);
-  //mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
-  // JNI must use non transactional mode.
-  //obj->SetField8<false>(MemberOffset(offset), newValue);
+    ScopedFastNativeObjectAccess soa(env);
+    mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
+    // JNI must use non transactional mode.
+    obj->SetField8(MemberOffset(offset), newValue);
 }
 
 static jchar Unsafe_getChar(JNIEnv* env, jobject, jobject javaObj, jlong offset) {
-  // TODO(haaawk): Fix this.
-  //ScopedFastNativeObjectAccess soa(env);
-  //mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
-  //return obj->GetField16(MemberOffset(offset));
-  return 0;
+    ScopedFastNativeObjectAccess soa(env);
+    mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
+    return obj->GetField16(MemberOffset(offset));
 }
 
 static void Unsafe_putChar(JNIEnv* env, jobject, jobject javaObj, jlong offset, jchar newValue) {
-  // TODO(haaawk): Fix this.
-  //ScopedFastNativeObjectAccess soa(env);
-  //mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
-  // JNI must use non transactional mode.
-  //obj->SetField16<false>(MemberOffset(offset), newValue);
+    ScopedFastNativeObjectAccess soa(env);
+    mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
+    // JNI must use non transactional mode.
+    obj->SetField16(MemberOffset(offset), newValue);
 }
 
 static jshort Unsafe_getShort(JNIEnv* env, jobject, jobject javaObj, jlong offset) {
-  // TODO(haaawk): Fix this.
-  //ScopedFastNativeObjectAccess soa(env);
-  //mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
-  //return obj->GetField16(MemberOffset(offset));
-  return 0;
+    ScopedFastNativeObjectAccess soa(env);
+    mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
+    return obj->GetField16(MemberOffset(offset));
 }
 
 static void Unsafe_putShort(JNIEnv* env, jobject, jobject javaObj, jlong offset, jshort newValue) {
-  // TODO(haaawk): Fix this.
-  //ScopedFastNativeObjectAccess soa(env);
-  //mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
-  // JNI must use non transactional mode.
-  //obj->SetField16<false>(MemberOffset(offset), newValue);
+    ScopedFastNativeObjectAccess soa(env);
+    mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
+    // JNI must use non transactional mode.
+    obj->SetField16<false>(MemberOffset(offset), newValue);
 }
 
 static jfloat Unsafe_getFloat(JNIEnv* env, jobject, jobject javaObj, jlong offset) {