ART: Make Handle trivially-copyable
Use default copy constructor and copy assignment to make Handle
trivially copyable. Do the same for MutableHandle.
Fix up unused Handle warnings. Add asserts in the HandleScope
test.
Bug: 32619234
Test: m test-art-host
Change-Id: I151f0bdbeeb131a6fc5c44610f345663ebe96c09
diff --git a/runtime/handle.h b/runtime/handle.h
index d33d4a6..3db3be2 100644
--- a/runtime/handle.h
+++ b/runtime/handle.h
@@ -42,13 +42,9 @@
Handle() : reference_(nullptr) {
}
- ALWAYS_INLINE Handle(const Handle<T>& handle) : reference_(handle.reference_) {
- }
+ ALWAYS_INLINE Handle(const Handle<T>& handle) = default;
- ALWAYS_INLINE Handle<T>& operator=(const Handle<T>& handle) {
- reference_ = handle.reference_;
- return *this;
- }
+ ALWAYS_INLINE Handle<T>& operator=(const Handle<T>& handle) = default;
ALWAYS_INLINE explicit Handle(StackReference<T>* reference) : reference_(reference) {
}
@@ -109,15 +105,10 @@
}
ALWAYS_INLINE MutableHandle(const MutableHandle<T>& handle)
- REQUIRES_SHARED(Locks::mutator_lock_)
- : Handle<T>(handle.reference_) {
- }
+ REQUIRES_SHARED(Locks::mutator_lock_) = default;
ALWAYS_INLINE MutableHandle<T>& operator=(const MutableHandle<T>& handle)
- REQUIRES_SHARED(Locks::mutator_lock_) {
- Handle<T>::operator=(handle);
- return *this;
- }
+ REQUIRES_SHARED(Locks::mutator_lock_) = default;
ALWAYS_INLINE explicit MutableHandle(StackReference<T>* reference)
REQUIRES_SHARED(Locks::mutator_lock_)
diff --git a/runtime/handle_scope_test.cc b/runtime/handle_scope_test.cc
index 92063c4..aab1d9c 100644
--- a/runtime/handle_scope_test.cc
+++ b/runtime/handle_scope_test.cc
@@ -14,15 +14,27 @@
* limitations under the License.
*/
+#include <type_traits>
+
#include "base/enums.h"
#include "common_runtime_test.h"
#include "gtest/gtest.h"
+#include "handle.h"
#include "handle_scope-inl.h"
+#include "mirror/object.h"
#include "scoped_thread_state_change-inl.h"
#include "thread.h"
namespace art {
+// Handles are value objects and should be trivially copyable.
+static_assert(std::is_trivially_copyable<Handle<mirror::Object>>::value,
+ "Handle should be trivially copyable");
+static_assert(std::is_trivially_copyable<MutableHandle<mirror::Object>>::value,
+ "MutableHandle should be trivially copyable");
+static_assert(std::is_trivially_copyable<ScopedNullHandle<mirror::Object>>::value,
+ "ScopedNullHandle should be trivially copyable");
+
class HandleScopeTest : public CommonRuntimeTest {};
// Test the offsets computed for members of HandleScope. Because of cross-compiling
diff --git a/runtime/mirror/object.cc b/runtime/mirror/object.cc
index 8cfb60e..f5b9ab3 100644
--- a/runtime/mirror/object.cc
+++ b/runtime/mirror/object.cc
@@ -235,8 +235,6 @@
}
for (ObjPtr<Class> cur = c; cur != nullptr; cur = cur->GetSuperClass()) {
for (ArtField& field : cur->GetIFields()) {
- StackHandleScope<1> hs(Thread::Current());
- Handle<Object> h_object(hs.NewHandle(new_value));
if (field.GetOffset().Int32Value() == field_offset.Int32Value()) {
CHECK_NE(field.GetTypeAsPrimitiveType(), Primitive::kPrimNot);
// TODO: resolve the field type for moving GC.
diff --git a/runtime/monitor_test.cc b/runtime/monitor_test.cc
index 4ee46dc..4fbfe47 100644
--- a/runtime/monitor_test.cc
+++ b/runtime/monitor_test.cc
@@ -401,14 +401,11 @@
Thread* const self = Thread::Current();
ThreadPool thread_pool("the pool", 2);
ScopedObjectAccess soa(self);
- StackHandleScope<3> hs(self);
+ StackHandleScope<1> hs(self);
Handle<mirror::Object> obj1(
hs.NewHandle<mirror::Object>(mirror::String::AllocFromModifiedUtf8(self, "hello, world!")));
- Handle<mirror::Object> obj2(
- hs.NewHandle<mirror::Object>(mirror::String::AllocFromModifiedUtf8(self, "hello, world!")));
{
ObjectLock<mirror::Object> lock1(self, obj1);
- ObjectLock<mirror::Object> lock2(self, obj1);
{
ObjectTryLock<mirror::Object> trylock(self, obj1);
EXPECT_TRUE(trylock.Acquired());
diff --git a/runtime/proxy_test.cc b/runtime/proxy_test.cc
index 32a5582..fd7e56d 100644
--- a/runtime/proxy_test.cc
+++ b/runtime/proxy_test.cc
@@ -199,8 +199,6 @@
ScopedObjectAccess soa(Thread::Current());
jobject jclass_loader = LoadDex("Interfaces");
StackHandleScope<7> hs(soa.Self());
- Handle<mirror::ClassLoader> class_loader(
- hs.NewHandle(soa.Decode<mirror::ClassLoader>(jclass_loader)));
Handle<mirror::Class> proxyClass0;
Handle<mirror::Class> proxyClass1;