Support 64-bit volatiles and reference/pointer volatiles.
Change-Id: I62c0751747767c02d6c57afd0fce3db6c8b02510
diff --git a/src/object.h b/src/object.h
index ed41494..b9cab1d 100644
--- a/src/object.h
+++ b/src/object.h
@@ -17,12 +17,10 @@
#ifndef ART_SRC_OBJECT_H_
#define ART_SRC_OBJECT_H_
-#include <cutils/atomic.h>
-#include <cutils/atomic-inline.h>
-
#include <vector>
#include "UniquePtr.h"
+#include "atomic.h"
#include "casts.h"
#include "constants.h"
#include "globals.h"
@@ -349,32 +347,18 @@
// Accessors for Java type fields
template<class T>
T GetFieldObject(MemberOffset field_offset, bool is_volatile) const {
- Heap::VerifyObject(this);
- DCHECK(Thread::Current() == NULL ||
- Thread::Current()->CanAccessDirectReferences());
- const byte* raw_addr = reinterpret_cast<const byte*>(this) +
- field_offset.Int32Value();
- if (is_volatile) {
- UNIMPLEMENTED(WARNING);
- }
- T result = *reinterpret_cast<T const *>(raw_addr);
+ DCHECK(Thread::Current() == NULL || Thread::Current()->CanAccessDirectReferences());
+ T result = reinterpret_cast<T>(GetField32(field_offset, is_volatile));
Heap::VerifyObject(result);
return result;
}
- void SetFieldObject(MemberOffset offset, const Object* new_value,
- bool is_volatile) {
- // Avoid verifying this when initializing the Class*
- if (offset.Int32Value() != ClassOffset().Int32Value()) {
- Heap::VerifyObject(this);
- }
+ void SetFieldObject(MemberOffset field_offset, const Object* new_value, bool is_volatile, bool this_is_valid = true) {
Heap::VerifyObject(new_value);
- byte* raw_addr = reinterpret_cast<byte*>(this) + offset.Int32Value();
- if (is_volatile) {
- UNIMPLEMENTED(WARNING);
+ SetField32(field_offset, reinterpret_cast<uint32_t>(new_value), is_volatile, this_is_valid);
+ if (new_value != NULL) {
+ Heap::WriteBarrier(this);
}
- *reinterpret_cast<const Object**>(raw_addr) = new_value;
- // TODO: write barrier
}
uint32_t GetField32(MemberOffset field_offset, bool is_volatile) const {
@@ -388,9 +372,11 @@
}
}
- void SetField32(MemberOffset offset, uint32_t new_value, bool is_volatile) {
- Heap::VerifyObject(this);
- byte* raw_addr = reinterpret_cast<byte*>(this) + offset.Int32Value();
+ void SetField32(MemberOffset field_offset, uint32_t new_value, bool is_volatile, bool this_is_valid = true) {
+ if (this_is_valid) {
+ Heap::VerifyObject(this);
+ }
+ byte* raw_addr = reinterpret_cast<byte*>(this) + field_offset.Int32Value();
uint32_t* word_addr = reinterpret_cast<uint32_t*>(raw_addr);
if (is_volatile) {
/*
@@ -409,42 +395,39 @@
uint64_t GetField64(MemberOffset field_offset, bool is_volatile) const {
Heap::VerifyObject(this);
const byte* raw_addr = reinterpret_cast<const byte*>(this) + field_offset.Int32Value();
+ const int64_t* addr = reinterpret_cast<const int64_t*>(raw_addr);
if (is_volatile) {
- UNIMPLEMENTED(WARNING);
+ uint64_t result = QuasiAtomicRead64(addr);
+ ANDROID_MEMBAR_FULL();
+ return result;
+ } else {
+ return *addr;
}
- return *reinterpret_cast<const uint64_t*>(raw_addr);
}
- void SetField64(MemberOffset offset, uint64_t new_value, bool is_volatile) {
+ void SetField64(MemberOffset field_offset, uint64_t new_value, bool is_volatile) {
Heap::VerifyObject(this);
- byte* raw_addr = reinterpret_cast<byte*>(this) + offset.Int32Value();
+ byte* raw_addr = reinterpret_cast<byte*>(this) + field_offset.Int32Value();
+ int64_t* addr = reinterpret_cast<int64_t*>(raw_addr);
if (is_volatile) {
- UNIMPLEMENTED(WARNING);
+ ANDROID_MEMBAR_STORE();
+ QuasiAtomicSwap64(new_value, addr);
+ // Post-store barrier not required due to use of atomic op or mutex.
+ } else {
+ *addr = new_value;
}
- *reinterpret_cast<uint64_t*>(raw_addr) = new_value;
}
protected:
// Accessors for non-Java type fields
template<class T>
T GetFieldPtr(MemberOffset field_offset, bool is_volatile) const {
- Heap::VerifyObject(this);
- const byte* raw_addr = reinterpret_cast<const byte*>(this) +
- field_offset.Int32Value();
- if (is_volatile) {
- UNIMPLEMENTED(WARNING);
- }
- return *reinterpret_cast<T const *>(raw_addr);
+ return reinterpret_cast<T>(GetField32(field_offset, is_volatile));
}
template<typename T>
- void SetFieldPtr(MemberOffset offset, T new_value, bool is_volatile) {
- Heap::VerifyObject(this);
- byte* raw_addr = reinterpret_cast<byte*>(this) + offset.Int32Value();
- if (is_volatile) {
- UNIMPLEMENTED(WARNING);
- }
- *reinterpret_cast<T*>(raw_addr) = new_value;
+ void SetFieldPtr(MemberOffset field_offset, T new_value, bool is_volatile) {
+ SetField32(field_offset, reinterpret_cast<uint32_t>(new_value), is_volatile);
}
private:
@@ -1793,8 +1776,7 @@
}
void SetIfTable(ObjectArray<InterfaceEntry>* new_iftable) {
- SetFieldObject(OFFSET_OF_OBJECT_MEMBER(Class, iftable_),
- new_iftable, false);
+ SetFieldObject(OFFSET_OF_OBJECT_MEMBER(Class, iftable_), new_iftable, false);
}
// Get instance fields
@@ -2091,7 +2073,7 @@
inline void Object::SetClass(Class* new_klass) {
// new_klass may be NULL prior to class linker initialization
- SetFieldObject(OFFSET_OF_OBJECT_MEMBER(Object, klass_), new_klass, false);
+ SetFieldObject(OFFSET_OF_OBJECT_MEMBER(Object, klass_), new_klass, false, false);
}
inline bool Object::InstanceOf(const Class* klass) const {