x86/x86-64 read barrier support for concurrent GC in Optimizing.
This first implementation uses slow paths to instrument heap
reference loads and GC root loads for the concurrent copying
collector, respectively calling the artReadBarrierSlow and
artReadBarrierForRootSlow (new) runtime entry points.
Notes:
- This implementation does not instrument HInvokeVirtual
nor HInvokeInterface instructions (for class reference
loads), as the corresponding read barriers are not stricly
required with the current concurrent copying collector.
- Intrinsics which may eventually call (on slow path) are
disabled when read barriers are enabled, as the current
slow path infrastructure does not support this case.
- When read barriers are enabled, the code generated for a
HArraySet instruction always go into the array set slow
path for object arrays (delegating the operation to the
runtime), as we are lacking a mechanism to keep a
temporary register live accross a runtime call (needed for
the instrumentation of type checking code, which requires
two successive read barriers).
Bug: 12687968
Change-Id: I14cd6107233c326389120336f93955b28ffbb329
diff --git a/runtime/entrypoints/quick/quick_field_entrypoints.cc b/runtime/entrypoints/quick/quick_field_entrypoints.cc
index 7361d34..7ec5fc5 100644
--- a/runtime/entrypoints/quick/quick_field_entrypoints.cc
+++ b/runtime/entrypoints/quick/quick_field_entrypoints.cc
@@ -14,14 +14,16 @@
* limitations under the License.
*/
+#include <stdint.h>
+
#include "art_field-inl.h"
#include "art_method-inl.h"
#include "callee_save_frame.h"
#include "dex_file-inl.h"
#include "entrypoints/entrypoint_utils-inl.h"
+#include "gc_root-inl.h"
#include "mirror/class-inl.h"
-
-#include <stdint.h>
+#include "mirror/object_reference.h"
namespace art {
@@ -560,13 +562,25 @@
// TODO: Currently the read barrier does not have a fast path. Ideally the slow path should only
// take one parameter "ref", which is given by the fast path.
extern "C" mirror::Object* artReadBarrierSlow(mirror::Object* ref ATTRIBUTE_UNUSED,
- mirror::Object* obj, uint32_t offset) {
- DCHECK(kUseReadBarrier);
+ mirror::Object* obj,
+ uint32_t offset) {
+ DCHECK(kEmitCompilerReadBarrier);
uint8_t* raw_addr = reinterpret_cast<uint8_t*>(obj) + offset;
mirror::HeapReference<mirror::Object>* ref_addr =
- reinterpret_cast<mirror::HeapReference<mirror::Object>*>(raw_addr);
- return ReadBarrier::Barrier<mirror::Object, kWithReadBarrier, true>(obj, MemberOffset(offset),
- ref_addr);
+ reinterpret_cast<mirror::HeapReference<mirror::Object>*>(raw_addr);
+ constexpr ReadBarrierOption kReadBarrierOption =
+ kUseReadBarrier ? kWithReadBarrier : kWithoutReadBarrier;
+ mirror::Object* result =
+ ReadBarrier::Barrier<mirror::Object, kReadBarrierOption, true>(obj,
+ MemberOffset(offset),
+ ref_addr);
+ return result;
+}
+
+extern "C" mirror::Object* artReadBarrierForRootSlow(GcRoot<mirror::Object>* root) {
+ DCHECK(kEmitCompilerReadBarrier);
+ // TODO: Pass a GcRootSource object as second argument to GcRoot::Read?
+ return root->Read();
}
} // namespace art