Revert "Revert "Revert "Revert "Add intrinsic for Reference.get()""""
Fixed TargetReg issue causing build failure for x86.
This reverts commit 9e82bd3f0ce9e5f5777bea2f752ff3e251d32f9f.
Change-Id: I7e6a526954467aaf68deeed999880dfe9aa5f06e
diff --git a/runtime/mirror/class-inl.h b/runtime/mirror/class-inl.h
index 349d4a3..329a984 100644
--- a/runtime/mirror/class-inl.h
+++ b/runtime/mirror/class-inl.h
@@ -30,6 +30,7 @@
#include "iftable.h"
#include "object_array-inl.h"
#include "read_barrier-inl.h"
+#include "reference-inl.h"
#include "runtime.h"
#include "string.h"
@@ -591,6 +592,11 @@
return this == ArtMethod::GetJavaLangReflectArtMethod<kReadBarrierOption>();
}
+template<ReadBarrierOption kReadBarrierOption>
+inline bool Class::IsReferenceClass() const {
+ return this == Reference::GetJavaLangRefReference<kReadBarrierOption>();
+}
+
template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
inline bool Class::IsClassClass() {
Class* java_lang_Class = GetClass<kVerifyFlags, kReadBarrierOption>()->
@@ -642,6 +648,30 @@
return GetFieldObject<ObjectArray<ObjectArray<Class>>>(field_offset);
}
+inline MemberOffset Class::GetDisableIntrinsicFlagOffset() {
+ CHECK(IsReferenceClass());
+ // First static field
+ DCHECK(GetSFields()->Get(0)->IsArtField());
+ DCHECK_STREQ(GetSFields()->Get(0)->GetName(), "disableIntrinsic");
+ return GetSFields()->Get(0)->GetOffset();
+}
+
+inline MemberOffset Class::GetSlowPathFlagOffset() {
+ CHECK(IsReferenceClass());
+ // Second static field
+ DCHECK(GetSFields()->Get(1)->IsArtField());
+ DCHECK_STREQ(GetSFields()->Get(1)->GetName(), "slowPathEnabled");
+ return GetSFields()->Get(1)->GetOffset();
+}
+
+inline bool Class::GetSlowPathEnabled() {
+ return GetField32(GetSlowPathFlagOffset());
+}
+
+inline void Class::SetSlowPath(bool enabled) {
+ SetField32<false>(GetSlowPathFlagOffset(), enabled);
+}
+
inline void Class::InitializeClassVisitor::operator()(
mirror::Object* obj, size_t usable_size) const {
DCHECK_LE(class_size_, usable_size);
diff --git a/runtime/mirror/class.h b/runtime/mirror/class.h
index 0f42044..648bdde 100644
--- a/runtime/mirror/class.h
+++ b/runtime/mirror/class.h
@@ -261,7 +261,7 @@
}
template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
- bool IsReferenceClass() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ bool IsTypeOfReferenceClass() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
return (GetAccessFlags<kVerifyFlags>() & kAccClassIsReference) != 0;
}
@@ -419,6 +419,9 @@
template<ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
bool IsArtMethodClass() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ template<ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
+ bool IsReferenceClass() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
static MemberOffset ComponentTypeOffset() {
return OFFSET_OF_OBJECT_MEMBER(Class, component_type_);
}
@@ -976,6 +979,12 @@
// For proxy class only.
ObjectArray<ObjectArray<Class>>* GetThrows() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ // For reference class only.
+ MemberOffset GetDisableIntrinsicFlagOffset() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ MemberOffset GetSlowPathFlagOffset() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ bool GetSlowPathEnabled() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ void SetSlowPath(bool enabled) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
// Used to initialize a class in the allocation code path to ensure it is guarded by a StoreStore
// fence.
class InitializeClassVisitor {
diff --git a/runtime/mirror/object-inl.h b/runtime/mirror/object-inl.h
index 3d45683..9dbfb56 100644
--- a/runtime/mirror/object-inl.h
+++ b/runtime/mirror/object-inl.h
@@ -249,7 +249,7 @@
template<VerifyObjectFlags kVerifyFlags>
inline bool Object::IsReferenceInstance() {
- return GetClass<kVerifyFlags>()->IsReferenceClass();
+ return GetClass<kVerifyFlags>()->IsTypeOfReferenceClass();
}
template<VerifyObjectFlags kVerifyFlags>
@@ -806,7 +806,7 @@
} else {
DCHECK(!klass->IsVariableSize());
VisitInstanceFieldsReferences<kVisitClass>(klass, visitor);
- if (UNLIKELY(klass->IsReferenceClass<kVerifyNone>())) {
+ if (UNLIKELY(klass->IsTypeOfReferenceClass<kVerifyNone>())) {
ref_visitor(klass, AsReference());
}
}
diff --git a/runtime/mirror/object.cc b/runtime/mirror/object.cc
index 5f88d54..bc5cbcb 100644
--- a/runtime/mirror/object.cc
+++ b/runtime/mirror/object.cc
@@ -57,7 +57,7 @@
ALWAYS_INLINE SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
// Copy java.lang.ref.Reference.referent which isn't visited in
// Object::VisitReferences().
- DCHECK(klass->IsReferenceClass());
+ DCHECK(klass->IsTypeOfReferenceClass());
this->operator()(ref, mirror::Reference::ReferentOffset(), false);
}
diff --git a/runtime/mirror/reference-inl.h b/runtime/mirror/reference-inl.h
index 43767c8..b353402 100644
--- a/runtime/mirror/reference-inl.h
+++ b/runtime/mirror/reference-inl.h
@@ -22,6 +22,11 @@
namespace art {
namespace mirror {
+inline uint32_t Reference::ClassSize() {
+ uint32_t vtable_entries = Object::kVTableLength + 5;
+ return Class::ComputeClassSize(false, vtable_entries, 2, 0, 0);
+}
+
inline bool Reference::IsEnqueuable() {
// Not using volatile reads as an optimization since this is only called with all the mutators
// suspended.
diff --git a/runtime/mirror/reference.cc b/runtime/mirror/reference.cc
new file mode 100644
index 0000000..077cd4b
--- /dev/null
+++ b/runtime/mirror/reference.cc
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+#include "reference.h"
+
+namespace art {
+namespace mirror {
+
+Class* Reference::java_lang_ref_Reference_ = nullptr;
+
+void Reference::SetClass(Class* java_lang_ref_Reference) {
+ CHECK(java_lang_ref_Reference_ == nullptr);
+ CHECK(java_lang_ref_Reference != nullptr);
+ java_lang_ref_Reference_ = java_lang_ref_Reference;
+}
+
+void Reference::ResetClass() {
+ CHECK(java_lang_ref_Reference_ != nullptr);
+ java_lang_ref_Reference_ = nullptr;
+}
+
+void Reference::VisitRoots(RootCallback* callback, void* arg) {
+ if (java_lang_ref_Reference_ != nullptr) {
+ callback(reinterpret_cast<mirror::Object**>(&java_lang_ref_Reference_),
+ arg, 0, kRootStickyClass);
+ }
+}
+
+} // namespace mirror
+} // namespace art
diff --git a/runtime/mirror/reference.h b/runtime/mirror/reference.h
index 9c9d87b..07d47d3 100644
--- a/runtime/mirror/reference.h
+++ b/runtime/mirror/reference.h
@@ -17,7 +17,11 @@
#ifndef ART_RUNTIME_MIRROR_REFERENCE_H_
#define ART_RUNTIME_MIRROR_REFERENCE_H_
+#include "class.h"
#include "object.h"
+#include "object_callbacks.h"
+#include "read_barrier.h"
+#include "thread.h"
namespace art {
@@ -36,6 +40,14 @@
// C++ mirror of java.lang.ref.Reference
class MANAGED Reference : public Object {
public:
+ // Size of java.lang.ref.Reference.class.
+ static uint32_t ClassSize();
+
+ // Size of an instance of java.lang.ref.Reference.
+ static constexpr uint32_t InstanceSize() {
+ return sizeof(Reference);
+ }
+
static MemberOffset PendingNextOffset() {
return OFFSET_OF_OBJECT_MEMBER(Reference, pending_next_);
}
@@ -80,6 +92,16 @@
bool IsEnqueuable() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ template<ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
+ static Class* GetJavaLangRefReference() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ DCHECK(java_lang_ref_Reference_ != nullptr);
+ return ReadBarrier::BarrierForRoot<mirror::Class, kReadBarrierOption>(
+ &java_lang_ref_Reference_);
+ }
+ static void SetClass(Class* klass);
+ static void ResetClass(void);
+ static void VisitRoots(RootCallback* callback, void* arg);
+
private:
// Note: This avoids a read barrier, it should only be used by the GC.
HeapReference<Object>* GetReferentReferenceAddr() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
@@ -92,6 +114,8 @@
HeapReference<Reference> queue_next_; // Note this is Java volatile:
HeapReference<Object> referent_; // Note this is Java volatile:
+ static Class* java_lang_ref_Reference_;
+
friend struct art::ReferenceOffsets; // for verifying offset information
friend class gc::ReferenceProcessor;
friend class gc::ReferenceQueue;