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) {