summaryrefslogtreecommitdiffstats
path: root/runtime
diff options
context:
space:
mode:
authorHiroshi Yamauchi <yamauchi@google.com>2014-04-01 17:58:30 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2014-04-01 17:58:30 +0000
commit79b1bf0ba1580cef94412ac3a62904ac89e6dfbc (patch)
tree17d7b4bc94f3421e1d4c0646287a7864d05da801 /runtime
parente0309ad355e778fe692beb8968bf8aa7edbd3302 (diff)
parent624468cd401cc1ac0dd70c746301e0788a597759 (diff)
downloadart-79b1bf0ba1580cef94412ac3a62904ac89e6dfbc.zip
art-79b1bf0ba1580cef94412ac3a62904ac89e6dfbc.tar.gz
art-79b1bf0ba1580cef94412ac3a62904ac89e6dfbc.tar.bz2
Merge "Make the support code for read barriers a bit more general."
Diffstat (limited to 'runtime')
-rw-r--r--runtime/asm_support.h4
-rw-r--r--runtime/class_linker.cc8
-rw-r--r--runtime/class_linker_test.cc14
-rw-r--r--runtime/gc/collector/mark_sweep.cc12
-rw-r--r--runtime/gc/collector/semi_space-inl.h4
-rw-r--r--runtime/gc/collector/semi_space.cc12
-rw-r--r--runtime/gc/heap-inl.h8
-rw-r--r--runtime/gc/heap.cc12
-rw-r--r--runtime/gc/space/image_space.cc6
-rw-r--r--runtime/gc/space/space_test.h4
-rw-r--r--runtime/globals.h16
-rw-r--r--runtime/mirror/object-inl.h32
-rw-r--r--runtime/mirror/object.h14
-rw-r--r--runtime/read_barrier.h (renamed from runtime/brooks_pointer.h)22
14 files changed, 99 insertions, 69 deletions
diff --git a/runtime/asm_support.h b/runtime/asm_support.h
index 0c1a72a..8ef407d 100644
--- a/runtime/asm_support.h
+++ b/runtime/asm_support.h
@@ -17,7 +17,7 @@
#ifndef ART_RUNTIME_ASM_SUPPORT_H_
#define ART_RUNTIME_ASM_SUPPORT_H_
-#include "brooks_pointer.h"
+#include "read_barrier.h"
// Value loaded into rSUSPEND for quick. When this value is counted down to zero we do a suspend
// check.
@@ -27,7 +27,7 @@
#define CLASS_OFFSET 0
#define LOCK_WORD_OFFSET 4
-#ifndef USE_BROOKS_POINTER
+#ifndef USE_BAKER_OR_BROOKS_READ_BARRIER
// Offsets within java.lang.Class.
#define CLASS_COMPONENT_TYPE_OFFSET 12
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index 08ea123..3957493 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -206,8 +206,8 @@ void ClassLinker::InitFromCompiler(const std::vector<const DexFile*>& boot_class
CHECK(java_lang_Class.get() != NULL);
mirror::Class::SetClassClass(java_lang_Class.get());
java_lang_Class->SetClass(java_lang_Class.get());
- if (kUseBrooksPointer) {
- java_lang_Class->AssertSelfBrooksPointer();
+ if (kUseBakerOrBrooksReadBarrier) {
+ java_lang_Class->AssertReadBarrierPointer();
}
java_lang_Class->SetClassSize(sizeof(mirror::ClassClass));
heap->DecrementDisableMovingGC(self);
@@ -1864,8 +1864,8 @@ void ClassLinker::LoadClass(const DexFile& dex_file,
CHECK(descriptor != NULL);
klass->SetClass(GetClassRoot(kJavaLangClass));
- if (kUseBrooksPointer) {
- klass->AssertSelfBrooksPointer();
+ if (kUseBakerOrBrooksReadBarrier) {
+ klass->AssertReadBarrierPointer();
}
uint32_t access_flags = dex_class_def.access_flags_;
// Make sure that none of our runtime-only flags are set.
diff --git a/runtime/class_linker_test.cc b/runtime/class_linker_test.cc
index 7eb7b01..5b72a44 100644
--- a/runtime/class_linker_test.cc
+++ b/runtime/class_linker_test.cc
@@ -452,9 +452,9 @@ struct ObjectOffsets : public CheckOffsets<mirror::Object> {
// alphabetical 32-bit
offsets.push_back(CheckOffset(OFFSETOF_MEMBER(mirror::Object, monitor_), "shadow$_monitor_"));
-#ifdef USE_BROOKS_POINTER
- offsets.push_back(CheckOffset(OFFSETOF_MEMBER(mirror::Object, x_brooks_ptr_), "shadow$_x_brooks_ptr_"));
- offsets.push_back(CheckOffset(OFFSETOF_MEMBER(mirror::Object, x_padding_), "shadow$_x_padding_"));
+#ifdef USE_BAKER_OR_BROOKS_READ_BARRIER
+ offsets.push_back(CheckOffset(OFFSETOF_MEMBER(mirror::Object, x_rb_ptr_), "shadow$_x_rb_ptr_"));
+ offsets.push_back(CheckOffset(OFFSETOF_MEMBER(mirror::Object, x_xpadding_), "shadow$_x_xpadding_"));
#endif
};
};
@@ -731,7 +731,7 @@ TEST_F(ClassLinkerTest, FindClass) {
EXPECT_FALSE(JavaLangObject->IsSynthetic());
EXPECT_EQ(2U, JavaLangObject->NumDirectMethods());
EXPECT_EQ(11U, JavaLangObject->NumVirtualMethods());
- if (!kUseBrooksPointer) {
+ if (!kUseBakerOrBrooksReadBarrier) {
EXPECT_EQ(2U, JavaLangObject->NumInstanceFields());
} else {
EXPECT_EQ(4U, JavaLangObject->NumInstanceFields());
@@ -740,11 +740,11 @@ TEST_F(ClassLinkerTest, FindClass) {
EXPECT_STREQ(fh.GetName(), "shadow$_klass_");
fh.ChangeField(JavaLangObject->GetInstanceField(1));
EXPECT_STREQ(fh.GetName(), "shadow$_monitor_");
- if (kUseBrooksPointer) {
+ if (kUseBakerOrBrooksReadBarrier) {
fh.ChangeField(JavaLangObject->GetInstanceField(2));
- EXPECT_STREQ(fh.GetName(), "shadow$_x_brooks_ptr_");
+ EXPECT_STREQ(fh.GetName(), "shadow$_x_rb_ptr_");
fh.ChangeField(JavaLangObject->GetInstanceField(3));
- EXPECT_STREQ(fh.GetName(), "shadow$_x_padding_");
+ EXPECT_STREQ(fh.GetName(), "shadow$_x_xpadding_");
}
EXPECT_EQ(0U, JavaLangObject->NumStaticFields());
diff --git a/runtime/gc/collector/mark_sweep.cc b/runtime/gc/collector/mark_sweep.cc
index 91ccd64..ca2d0bd 100644
--- a/runtime/gc/collector/mark_sweep.cc
+++ b/runtime/gc/collector/mark_sweep.cc
@@ -343,9 +343,9 @@ void MarkSweep::MarkHeapReferenceCallback(mirror::HeapReference<mirror::Object>*
inline void MarkSweep::MarkObjectNonNull(Object* obj) {
DCHECK(obj != nullptr);
- if (kUseBrooksPointer) {
- // Verify all the objects have the correct Brooks pointer installed.
- obj->AssertSelfBrooksPointer();
+ if (kUseBakerOrBrooksReadBarrier) {
+ // Verify all the objects have the correct pointer installed.
+ obj->AssertReadBarrierPointer();
}
if (immune_region_.ContainsObject(obj)) {
if (kCountMarkedObjects) {
@@ -415,9 +415,9 @@ bool MarkSweep::MarkLargeObject(const Object* obj, bool set) {
inline bool MarkSweep::MarkObjectParallel(const Object* obj) {
DCHECK(obj != nullptr);
- if (kUseBrooksPointer) {
- // Verify all the objects have the correct Brooks pointer installed.
- obj->AssertSelfBrooksPointer();
+ if (kUseBakerOrBrooksReadBarrier) {
+ // Verify all the objects have the correct pointer installed.
+ obj->AssertReadBarrierPointer();
}
if (immune_region_.ContainsObject(obj)) {
DCHECK(IsMarked(obj));
diff --git a/runtime/gc/collector/semi_space-inl.h b/runtime/gc/collector/semi_space-inl.h
index d60298b..df731ff 100644
--- a/runtime/gc/collector/semi_space-inl.h
+++ b/runtime/gc/collector/semi_space-inl.h
@@ -45,9 +45,9 @@ inline void SemiSpace::MarkObject(
if (obj == nullptr) {
return;
}
- if (kUseBrooksPointer) {
+ if (kUseBakerOrBrooksReadBarrier) {
// Verify all the objects have the correct forward pointer installed.
- obj->AssertSelfBrooksPointer();
+ obj->AssertReadBarrierPointer();
}
if (!immune_region_.ContainsObject(obj)) {
if (from_space_->HasAddress(obj)) {
diff --git a/runtime/gc/collector/semi_space.cc b/runtime/gc/collector/semi_space.cc
index 222bd63..1366858 100644
--- a/runtime/gc/collector/semi_space.cc
+++ b/runtime/gc/collector/semi_space.cc
@@ -561,11 +561,13 @@ mirror::Object* SemiSpace::MarkNonForwardedObject(mirror::Object* obj) {
// references.
saved_bytes_ +=
CopyAvoidingDirtyingPages(reinterpret_cast<void*>(forward_address), obj, object_size);
- if (kUseBrooksPointer) {
- obj->AssertSelfBrooksPointer();
- DCHECK_EQ(forward_address->GetBrooksPointer(), obj);
- forward_address->SetBrooksPointer(forward_address);
- forward_address->AssertSelfBrooksPointer();
+ if (kUseBakerOrBrooksReadBarrier) {
+ obj->AssertReadBarrierPointer();
+ if (kUseBrooksReadBarrier) {
+ DCHECK_EQ(forward_address->GetReadBarrierPointer(), obj);
+ forward_address->SetReadBarrierPointer(forward_address);
+ }
+ forward_address->AssertReadBarrierPointer();
}
if (to_space_live_bitmap_ != nullptr) {
to_space_live_bitmap_->Set(forward_address);
diff --git a/runtime/gc/heap-inl.h b/runtime/gc/heap-inl.h
index 8bfe793..25f20d6 100644
--- a/runtime/gc/heap-inl.h
+++ b/runtime/gc/heap-inl.h
@@ -73,9 +73,11 @@ inline mirror::Object* Heap::AllocObjectWithAllocator(Thread* self, mirror::Clas
DCHECK_GT(bytes_allocated, 0u);
DCHECK_GT(usable_size, 0u);
obj->SetClass(klass);
- if (kUseBrooksPointer) {
- obj->SetBrooksPointer(obj);
- obj->AssertSelfBrooksPointer();
+ if (kUseBakerOrBrooksReadBarrier) {
+ if (kUseBrooksReadBarrier) {
+ obj->SetReadBarrierPointer(obj);
+ }
+ obj->AssertReadBarrierPointer();
}
if (collector::SemiSpace::kUseRememberedSet && UNLIKELY(allocator == kAllocatorTypeNonMoving)) {
// (Note this if statement will be constant folded away for the
diff --git a/runtime/gc/heap.cc b/runtime/gc/heap.cc
index 1a32a9a..bc50668 100644
--- a/runtime/gc/heap.cc
+++ b/runtime/gc/heap.cc
@@ -1605,11 +1605,13 @@ class ZygoteCompactingCollector FINAL : public collector::SemiSpace {
}
// Copy the object over to its new location.
memcpy(reinterpret_cast<void*>(forward_address), obj, object_size);
- if (kUseBrooksPointer) {
- obj->AssertSelfBrooksPointer();
- DCHECK_EQ(forward_address->GetBrooksPointer(), obj);
- forward_address->SetBrooksPointer(forward_address);
- forward_address->AssertSelfBrooksPointer();
+ if (kUseBakerOrBrooksReadBarrier) {
+ obj->AssertReadBarrierPointer();
+ if (kUseBrooksReadBarrier) {
+ DCHECK_EQ(forward_address->GetReadBarrierPointer(), obj);
+ forward_address->SetReadBarrierPointer(forward_address);
+ }
+ forward_address->AssertReadBarrierPointer();
}
return forward_address;
}
diff --git a/runtime/gc/space/image_space.cc b/runtime/gc/space/image_space.cc
index bb52c66..9a2815a 100644
--- a/runtime/gc/space/image_space.cc
+++ b/runtime/gc/space/image_space.cc
@@ -166,10 +166,8 @@ void ImageSpace::VerifyImageAllocations() {
mirror::Object* obj = reinterpret_cast<mirror::Object*>(current);
CHECK(live_bitmap_->Test(obj));
CHECK(obj->GetClass() != nullptr) << "Image object at address " << obj << " has null class";
- if (kUseBrooksPointer) {
- CHECK(obj->GetBrooksPointer() == obj)
- << "Bad Brooks pointer: obj=" << reinterpret_cast<void*>(obj)
- << " brooks_ptr=" << reinterpret_cast<void*>(obj->GetBrooksPointer());
+ if (kUseBakerOrBrooksReadBarrier) {
+ obj->AssertReadBarrierPointer();
}
current += RoundUp(obj->SizeOf(), kObjectAlignment);
}
diff --git a/runtime/gc/space/space_test.h b/runtime/gc/space/space_test.h
index 6d3602c..5c735df 100644
--- a/runtime/gc/space/space_test.h
+++ b/runtime/gc/space/space_test.h
@@ -85,8 +85,8 @@ class SpaceTest : public CommonRuntimeTest {
EXPECT_GE(size, SizeOfZeroLengthByteArray());
EXPECT_TRUE(byte_array_class != nullptr);
o->SetClass(byte_array_class);
- if (kUseBrooksPointer) {
- o->SetBrooksPointer(o);
+ if (kUseBrooksReadBarrier) {
+ o->SetReadBarrierPointer(o);
}
mirror::Array* arr = o->AsArray<kVerifyNone>();
size_t header_size = SizeOfZeroLengthByteArray();
diff --git a/runtime/globals.h b/runtime/globals.h
index 9c6fa0d..f2d6862 100644
--- a/runtime/globals.h
+++ b/runtime/globals.h
@@ -19,7 +19,7 @@
#include <stddef.h>
#include <stdint.h>
-#include "brooks_pointer.h"
+#include "read_barrier.h"
namespace art {
@@ -97,12 +97,20 @@ static constexpr bool kMovingMethods = false;
// code, if possible.
static constexpr bool kEmbedClassInCode = true;
-#ifdef USE_BROOKS_POINTER
-static constexpr bool kUseBrooksPointer = true;
+#ifdef USE_BAKER_READ_BARRIER
+static constexpr bool kUseBakerReadBarrier = true;
#else
-static constexpr bool kUseBrooksPointer = false;
+static constexpr bool kUseBakerReadBarrier = false;
#endif
+#ifdef USE_BROOKS_READ_BARRIER
+static constexpr bool kUseBrooksReadBarrier = true;
+#else
+static constexpr bool kUseBrooksReadBarrier = false;
+#endif
+
+static constexpr bool kUseBakerOrBrooksReadBarrier = kUseBakerReadBarrier || kUseBrooksReadBarrier;
+
// If true, references within the heap are poisoned (negated).
static constexpr bool kPoisonHeapReferences = false;
diff --git a/runtime/mirror/object-inl.h b/runtime/mirror/object-inl.h
index 527b8a6..b6c140d 100644
--- a/runtime/mirror/object-inl.h
+++ b/runtime/mirror/object-inl.h
@@ -93,33 +93,41 @@ inline void Object::Wait(Thread* self, int64_t ms, int32_t ns) {
Monitor::Wait(self, this, ms, ns, true, kTimedWaiting);
}
-inline Object* Object::GetBrooksPointer() {
-#ifdef USE_BROOKS_POINTER
- DCHECK(kUseBrooksPointer);
- return GetFieldObject<Object, kVerifyNone>(OFFSET_OF_OBJECT_MEMBER(Object, x_brooks_ptr_), false);
+inline Object* Object::GetReadBarrierPointer() {
+#ifdef USE_BAKER_OR_BROOKS_READ_BARRIER
+ DCHECK(kUseBakerOrBrooksReadBarrier);
+ return GetFieldObject<Object, kVerifyNone>(OFFSET_OF_OBJECT_MEMBER(Object, x_rb_ptr_), false);
#else
LOG(FATAL) << "Unreachable";
return nullptr;
#endif
}
-inline void Object::SetBrooksPointer(Object* brooks_pointer) {
-#ifdef USE_BROOKS_POINTER
- DCHECK(kUseBrooksPointer);
+inline void Object::SetReadBarrierPointer(Object* rb_pointer) {
+#ifdef USE_BAKER_OR_BROOKS_READ_BARRIER
+ DCHECK(kUseBakerOrBrooksReadBarrier);
// We don't mark the card as this occurs as part of object allocation. Not all objects have
// backing cards, such as large objects.
SetFieldObjectWithoutWriteBarrier<false, false, kVerifyNone>(
- OFFSET_OF_OBJECT_MEMBER(Object, x_brooks_ptr_), brooks_pointer, false);
+ OFFSET_OF_OBJECT_MEMBER(Object, x_rb_ptr_), rb_pointer, false);
#else
LOG(FATAL) << "Unreachable";
#endif
}
-inline void Object::AssertSelfBrooksPointer() const {
-#ifdef USE_BROOKS_POINTER
- DCHECK(kUseBrooksPointer);
+inline void Object::AssertReadBarrierPointer() const {
+#if defined(USE_BAKER_READ_BARRIER)
+ DCHECK(kUseBakerReadBarrier);
Object* obj = const_cast<Object*>(this);
- DCHECK_EQ(obj, obj->GetBrooksPointer());
+ DCHECK(obj->GetReadBarrierPointer() == nullptr)
+ << "Bad Baker pointer: obj=" << reinterpret_cast<void*>(obj)
+ << " ptr=" << reinterpret_cast<void*>(obj->GetReadBarrierPointer());
+#elif defined(USE_BROOKS_READ_BARRIER)
+ DCHECK(kUseBrooksReadBarrier);
+ Object* obj = const_cast<Object*>(this);
+ DCHECK_EQ(obj, obj->GetReadBarrierPointer())
+ << "Bad Brooks pointer: obj=" << reinterpret_cast<void*>(obj)
+ << " ptr=" << reinterpret_cast<void*>(obj->GetReadBarrierPointer());
#else
LOG(FATAL) << "Unreachable";
#endif
diff --git a/runtime/mirror/object.h b/runtime/mirror/object.h
index 0a77828..1ac23ce 100644
--- a/runtime/mirror/object.h
+++ b/runtime/mirror/object.h
@@ -78,9 +78,9 @@ class MANAGED LOCKABLE Object {
template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
void SetClass(Class* new_klass) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- Object* GetBrooksPointer() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- void SetBrooksPointer(Object* brooks_pointer) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- void AssertSelfBrooksPointer() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ Object* GetReadBarrierPointer() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ void SetReadBarrierPointer(Object* rb_pointer) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ void AssertReadBarrierPointer() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// The verifier treats all interfaces as java.lang.Object and relies on runtime checks in
// invoke-interface to detect incompatible interface types.
@@ -289,12 +289,12 @@ class MANAGED LOCKABLE Object {
// Monitor and hash code information.
uint32_t monitor_;
-#ifdef USE_BROOKS_POINTER
- // Note names use a 'x' prefix and the x_brooks_ptr_ is of type int
+#ifdef USE_BAKER_OR_BROOKS_READ_BARRIER
+ // Note names use a 'x' prefix and the x_rb_ptr_ is of type int
// instead of Object to go with the alphabetical/by-type field order
// on the Java side.
- uint32_t x_brooks_ptr_; // For the Brooks pointer.
- uint32_t x_padding_; // For 8-byte alignment. TODO: get rid of this.
+ uint32_t x_rb_ptr_; // For the Baker or Brooks pointer.
+ uint32_t x_xpadding_; // For 8-byte alignment. TODO: get rid of this.
#endif
friend class art::ImageWriter;
diff --git a/runtime/brooks_pointer.h b/runtime/read_barrier.h
index 3dac6e9..ba0d830 100644
--- a/runtime/brooks_pointer.h
+++ b/runtime/read_barrier.h
@@ -14,14 +14,24 @@
* limitations under the License.
*/
-#ifndef ART_RUNTIME_BROOKS_POINTER_H_
-#define ART_RUNTIME_BROOKS_POINTER_H_
+#ifndef ART_RUNTIME_READ_BARRIER_H_
+#define ART_RUNTIME_READ_BARRIER_H_
// This is in a separate file (from globals.h) because asm_support.h
// (a C header, not C++) can't include globals.h.
-// Uncomment this and the two fields in Object.java (libcore) to
-// enable brooks pointers.
-// #define USE_BROOKS_POINTER
+// Uncomment one of the following two and the two fields in
+// Object.java (libcore) to enable baker or brooks pointers.
-#endif // ART_RUNTIME_BROOKS_POINTER_H_
+// #define USE_BAKER_READ_BARRIER
+// #define USE_BROOKS_READ_BARRIER
+
+#if defined(USE_BAKER_READ_BARRIER) || defined(USE_BROOKS_READ_BARRIER)
+#define USE_BAKER_OR_BROOKS_READ_BARRIER
+#endif
+
+#if defined(USE_BAKER_READ_BARRIER) && defined(USE_BROOKS_READ_BARRIER)
+#error "Only one of Baker or Brooks can be enabled at a time."
+#endif
+
+#endif // ART_RUNTIME_READ_BARRIER_H_