From 800ac2defde5d12b2f1f313c6b6162560cfa6fc7 Mon Sep 17 00:00:00 2001 From: Hiroshi Yamauchi Date: Wed, 2 Apr 2014 17:32:54 -0700 Subject: [PATCH] Insert an empty read barrier call. Bug: 12687968 Change-Id: Ie1d28658e16e09f6a983cb5c1f0d5b375b7ae069 --- runtime/asm_support.h | 2 +- runtime/gc/space/space_test.h | 9 +++++++-- runtime/globals.h | 2 +- runtime/mirror/object-inl.h | 37 ++++++++++++++++------------------ runtime/mirror/object.h | 2 +- runtime/read_barrier-inl.h | 47 +++++++++++++++++++++++++++++++++++++++++++ runtime/read_barrier.h | 31 +++++++++++++++++----------- runtime/read_barrier_c.h | 38 ++++++++++++++++++++++++++++++++++ 8 files changed, 131 insertions(+), 37 deletions(-) create mode 100644 runtime/read_barrier-inl.h create mode 100644 runtime/read_barrier_c.h diff --git a/runtime/asm_support.h b/runtime/asm_support.h index 8ef407d0a..62f359346 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 "read_barrier.h" +#include "read_barrier_c.h" // Value loaded into rSUSPEND for quick. When this value is counted down to zero we do a suspend // check. diff --git a/runtime/gc/space/space_test.h b/runtime/gc/space/space_test.h index 5c735df45..9896a4833 100644 --- a/runtime/gc/space/space_test.h +++ b/runtime/gc/space/space_test.h @@ -85,8 +85,13 @@ class SpaceTest : public CommonRuntimeTest { EXPECT_GE(size, SizeOfZeroLengthByteArray()); EXPECT_TRUE(byte_array_class != nullptr); o->SetClass(byte_array_class); - if (kUseBrooksReadBarrier) { - o->SetReadBarrierPointer(o); + if (kUseBakerOrBrooksReadBarrier) { + // Like the proper heap object allocation, install and verify + // the correct read barrier pointer. + if (kUseBrooksReadBarrier) { + o->SetReadBarrierPointer(o); + } + o->AssertReadBarrierPointer(); } mirror::Array* arr = o->AsArray(); size_t header_size = SizeOfZeroLengthByteArray(); diff --git a/runtime/globals.h b/runtime/globals.h index f2d686254..bd85d3b5e 100644 --- a/runtime/globals.h +++ b/runtime/globals.h @@ -19,7 +19,7 @@ #include #include -#include "read_barrier.h" +#include "read_barrier_c.h" namespace art { diff --git a/runtime/mirror/object-inl.h b/runtime/mirror/object-inl.h index b6c140d6d..a6db387a0 100644 --- a/runtime/mirror/object-inl.h +++ b/runtime/mirror/object-inl.h @@ -26,6 +26,7 @@ #include "class.h" #include "lock_word-inl.h" #include "monitor.h" +#include "read_barrier-inl.h" #include "runtime.h" #include "reference.h" #include "throwable.h" @@ -96,7 +97,7 @@ inline void Object::Wait(Thread* self, int64_t ms, int32_t ns) { inline Object* Object::GetReadBarrierPointer() { #ifdef USE_BAKER_OR_BROOKS_READ_BARRIER DCHECK(kUseBakerOrBrooksReadBarrier); - return GetFieldObject(OFFSET_OF_OBJECT_MEMBER(Object, x_rb_ptr_), false); + return GetFieldObject(OFFSET_OF_OBJECT_MEMBER(Object, x_rb_ptr_), false); #else LOG(FATAL) << "Unreachable"; return nullptr; @@ -116,21 +117,19 @@ inline void Object::SetReadBarrierPointer(Object* rb_pointer) { } inline void Object::AssertReadBarrierPointer() const { -#if defined(USE_BAKER_READ_BARRIER) - DCHECK(kUseBakerReadBarrier); - Object* obj = const_cast(this); - DCHECK(obj->GetReadBarrierPointer() == nullptr) - << "Bad Baker pointer: obj=" << reinterpret_cast(obj) - << " ptr=" << reinterpret_cast(obj->GetReadBarrierPointer()); -#elif defined(USE_BROOKS_READ_BARRIER) - DCHECK(kUseBrooksReadBarrier); - Object* obj = const_cast(this); - DCHECK_EQ(obj, obj->GetReadBarrierPointer()) - << "Bad Brooks pointer: obj=" << reinterpret_cast(obj) - << " ptr=" << reinterpret_cast(obj->GetReadBarrierPointer()); -#else - LOG(FATAL) << "Unreachable"; -#endif + if (kUseBakerReadBarrier) { + Object* obj = const_cast(this); + DCHECK(obj->GetReadBarrierPointer() == nullptr) + << "Bad Baker pointer: obj=" << reinterpret_cast(obj) + << " ptr=" << reinterpret_cast(obj->GetReadBarrierPointer()); + } else if (kUseBrooksReadBarrier) { + Object* obj = const_cast(this); + DCHECK_EQ(obj, obj->GetReadBarrierPointer()) + << "Bad Brooks pointer: obj=" << reinterpret_cast(obj) + << " ptr=" << reinterpret_cast(obj->GetReadBarrierPointer()); + } else { + LOG(FATAL) << "Unreachable"; + } } template @@ -470,19 +469,17 @@ inline bool Object::CasField64(MemberOffset field_offset, int64_t old_value, int return QuasiAtomic::Cas64(old_value, new_value, addr); } -template +template inline T* Object::GetFieldObject(MemberOffset field_offset, bool is_volatile) { if (kVerifyFlags & kVerifyThis) { VerifyObject(this); } byte* raw_addr = reinterpret_cast(this) + field_offset.Int32Value(); HeapReference* objref_addr = reinterpret_cast*>(raw_addr); - HeapReference objref = *objref_addr; - + T* result = ReadBarrier::Barrier(this, field_offset, objref_addr); if (UNLIKELY(is_volatile)) { QuasiAtomic::MembarLoadLoad(); // Ensure loads don't re-order. } - T* result = objref.AsMirrorPtr(); if (kVerifyFlags & kVerifyReads) { VerifyObject(result); } diff --git a/runtime/mirror/object.h b/runtime/mirror/object.h index 1ac23ce6c..f65220299 100644 --- a/runtime/mirror/object.h +++ b/runtime/mirror/object.h @@ -185,7 +185,7 @@ class MANAGED LOCKABLE Object { bool IsPhantomReferenceInstance() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); // Accessor for Java type fields. - template + template T* GetFieldObject(MemberOffset field_offset, bool is_volatile) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); template +inline MirrorType* ReadBarrier::Barrier( + mirror::Object* obj, MemberOffset offset, mirror::HeapReference* ref_addr) { + // Unused for now. + UNUSED(obj); + UNUSED(offset); + UNUSED(ref_addr); + if (kDoReadBarrier && kUseBakerReadBarrier) { + // To be implemented. + return ref_addr->AsMirrorPtr(); + } else if (kDoReadBarrier && kUseBrooksReadBarrier) { + // To be implemented. + return ref_addr->AsMirrorPtr(); + } else { + // No read barrier. + return ref_addr->AsMirrorPtr(); + } +} + +} // namespace art + +#endif // ART_RUNTIME_READ_BARRIER_INL_H_ diff --git a/runtime/read_barrier.h b/runtime/read_barrier.h index ba0d83042..6f5900447 100644 --- a/runtime/read_barrier.h +++ b/runtime/read_barrier.h @@ -17,21 +17,28 @@ #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. +#include "base/mutex.h" +#include "base/macros.h" +#include "offsets.h" +#include "read_barrier_c.h" -// Uncomment one of the following two and the two fields in -// Object.java (libcore) to enable baker or brooks pointers. +// This is a C++ (not C) header file, separate from read_barrier_c.h +// which needs to be a C header file for asm_support.h. -// #define USE_BAKER_READ_BARRIER -// #define USE_BROOKS_READ_BARRIER +namespace art { +namespace mirror { + class Object; + template class HeapReference; +} // namespace mirror -#if defined(USE_BAKER_READ_BARRIER) || defined(USE_BROOKS_READ_BARRIER) -#define USE_BAKER_OR_BROOKS_READ_BARRIER -#endif +class ReadBarrier { + public: + template + ALWAYS_INLINE static MirrorType* Barrier( + mirror::Object* obj, MemberOffset offset, mirror::HeapReference* ref_addr) + SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); +}; -#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 +} // namespace art #endif // ART_RUNTIME_READ_BARRIER_H_ diff --git a/runtime/read_barrier_c.h b/runtime/read_barrier_c.h new file mode 100644 index 000000000..f4af61f51 --- /dev/null +++ b/runtime/read_barrier_c.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ART_RUNTIME_READ_BARRIER_C_H_ +#define ART_RUNTIME_READ_BARRIER_C_H_ + +// This is a C (not C++) header file and is in a separate file (from +// globals.h) because asm_support.h is a C header file and can't +// include globals.h. + +// Uncomment one of the following two and the two fields in +// Object.java (libcore) to enable baker or brooks pointers. + +// #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_C_H_ -- 2.11.0