Add Handle/HandleScope and delete SirtRef.
Delete SirtRef and replaced it with Handle. Handles are value types
which wrap around StackReference*.
Renamed StackIndirectReferenceTable to HandleScope.
Added a scoped handle wrapper which wraps around an Object** and
restores it in its destructor.
Renamed Handle::get -> Get.
Bug: 8473721
Change-Id: Idbfebd4f35af629f0f43931b7c5184b334822c7a
diff --git a/runtime/class_linker_test.cc b/runtime/class_linker_test.cc
index b68ab4a..0db08aa 100644
--- a/runtime/class_linker_test.cc
+++ b/runtime/class_linker_test.cc
@@ -34,7 +34,7 @@
#include "mirror/proxy.h"
#include "mirror/reference.h"
#include "mirror/stack_trace_element.h"
-#include "sirt_ref.h"
+#include "handle_scope-inl.h"
namespace art {
@@ -99,9 +99,10 @@
mirror::ClassLoader* class_loader)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Thread* self = Thread::Current();
- SirtRef<mirror::ClassLoader> loader(self, class_loader);
- SirtRef<mirror::Class> array(self,
- class_linker_->FindClass(self, array_descriptor.c_str(), loader));
+ StackHandleScope<2> hs(self);
+ Handle<mirror::ClassLoader> loader(hs.NewHandle(class_loader));
+ Handle<mirror::Class> array(
+ hs.NewHandle(class_linker_->FindClass(self, array_descriptor.c_str(), loader)));
ClassHelper array_component_ch(array->GetComponentType());
EXPECT_STREQ(component_type.c_str(), array_component_ch.GetDescriptor());
EXPECT_EQ(class_loader, array->GetClassLoader());
@@ -109,10 +110,10 @@
AssertArrayClass(array_descriptor, array);
}
- void AssertArrayClass(const std::string& array_descriptor, const SirtRef<mirror::Class>& array)
+ void AssertArrayClass(const std::string& array_descriptor, const Handle<mirror::Class>& array)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- ClassHelper kh(array.get());
- ASSERT_TRUE(array.get() != NULL);
+ ClassHelper kh(array.Get());
+ ASSERT_TRUE(array.Get() != NULL);
ASSERT_TRUE(array->GetClass() != NULL);
ASSERT_EQ(array->GetClass(), array->GetClass()->GetClass());
EXPECT_TRUE(array->GetClass()->GetSuperClass() != NULL);
@@ -141,17 +142,17 @@
EXPECT_EQ(0U, array->NumVirtualMethods());
EXPECT_EQ(0U, array->NumInstanceFields());
EXPECT_EQ(0U, array->NumStaticFields());
- kh.ChangeClass(array.get());
+ kh.ChangeClass(array.Get());
EXPECT_EQ(2U, kh.NumDirectInterfaces());
EXPECT_TRUE(array->GetVTable() != NULL);
EXPECT_EQ(2, array->GetIfTableCount());
ASSERT_TRUE(array->GetIfTable() != NULL);
kh.ChangeClass(kh.GetDirectInterface(0));
EXPECT_STREQ(kh.GetDescriptor(), "Ljava/lang/Cloneable;");
- kh.ChangeClass(array.get());
+ kh.ChangeClass(array.Get());
kh.ChangeClass(kh.GetDirectInterface(1));
EXPECT_STREQ(kh.GetDescriptor(), "Ljava/io/Serializable;");
- EXPECT_EQ(class_linker_->FindArrayClass(self, array->GetComponentType()), array.get());
+ EXPECT_EQ(class_linker_->FindArrayClass(self, array->GetComponentType()), array.Get());
}
void AssertMethod(mirror::ArtMethod* method) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
@@ -182,9 +183,9 @@
EXPECT_TRUE(fh.GetType() != NULL);
}
- void AssertClass(const std::string& descriptor, const SirtRef<mirror::Class>& klass)
+ void AssertClass(const std::string& descriptor, const Handle<mirror::Class>& klass)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- ClassHelper kh(klass.get());
+ ClassHelper kh(klass.Get());
EXPECT_STREQ(descriptor.c_str(), kh.GetDescriptor());
if (descriptor == "Ljava/lang/Object;") {
EXPECT_FALSE(klass->HasSuperClass());
@@ -200,7 +201,7 @@
EXPECT_FALSE(klass->IsErroneous());
EXPECT_FALSE(klass->IsArrayClass());
EXPECT_TRUE(klass->GetComponentType() == NULL);
- EXPECT_TRUE(klass->IsInSamePackage(klass.get()));
+ EXPECT_TRUE(klass->IsInSamePackage(klass.Get()));
EXPECT_TRUE(mirror::Class::IsInSamePackage(kh.GetDescriptor(), kh.GetDescriptor()));
if (klass->IsInterface()) {
EXPECT_TRUE(klass->IsAbstract());
@@ -242,31 +243,31 @@
}
EXPECT_FALSE(klass->IsPrimitive());
- EXPECT_TRUE(klass->CanAccess(klass.get()));
+ EXPECT_TRUE(klass->CanAccess(klass.Get()));
for (size_t i = 0; i < klass->NumDirectMethods(); i++) {
mirror::ArtMethod* method = klass->GetDirectMethod(i);
AssertMethod(method);
EXPECT_TRUE(method->IsDirect());
- EXPECT_EQ(klass.get(), method->GetDeclaringClass());
+ EXPECT_EQ(klass.Get(), method->GetDeclaringClass());
}
for (size_t i = 0; i < klass->NumVirtualMethods(); i++) {
mirror::ArtMethod* method = klass->GetVirtualMethod(i);
AssertMethod(method);
EXPECT_FALSE(method->IsDirect());
- EXPECT_TRUE(method->GetDeclaringClass()->IsAssignableFrom(klass.get()));
+ EXPECT_TRUE(method->GetDeclaringClass()->IsAssignableFrom(klass.Get()));
}
for (size_t i = 0; i < klass->NumInstanceFields(); i++) {
mirror::ArtField* field = klass->GetInstanceField(i);
- AssertField(klass.get(), field);
+ AssertField(klass.Get(), field);
EXPECT_FALSE(field->IsStatic());
}
for (size_t i = 0; i < klass->NumStaticFields(); i++) {
mirror::ArtField* field = klass->GetStaticField(i);
- AssertField(klass.get(), field);
+ AssertField(klass.Get(), field);
EXPECT_TRUE(field->IsStatic());
}
@@ -294,7 +295,7 @@
}
size_t total_num_reference_instance_fields = 0;
- mirror::Class* k = klass.get();
+ mirror::Class* k = klass.Get();
while (k != NULL) {
total_num_reference_instance_fields += k->NumReferenceInstanceFields();
k = k->GetSuperClass();
@@ -306,12 +307,14 @@
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
ASSERT_TRUE(descriptor != NULL);
Thread* self = Thread::Current();
- SirtRef<mirror::Class> klass(self, class_linker_->FindSystemClass(self, descriptor.c_str()));
- ASSERT_TRUE(klass.get() != nullptr);
- EXPECT_STREQ(descriptor.c_str(), ClassHelper(klass.get()).GetDescriptor());
+ StackHandleScope<1> hs(self);
+ Handle<mirror::Class> klass(
+ hs.NewHandle(class_linker_->FindSystemClass(self, descriptor.c_str())));
+ ASSERT_TRUE(klass.Get() != nullptr);
+ EXPECT_STREQ(descriptor.c_str(), ClassHelper(klass.Get()).GetDescriptor());
EXPECT_EQ(class_loader, klass->GetClassLoader());
if (klass->IsPrimitive()) {
- AssertPrimitiveClass(descriptor, klass.get());
+ AssertPrimitiveClass(descriptor, klass.Get());
} else if (klass->IsArrayClass()) {
AssertArrayClass(descriptor, klass);
} else {
@@ -671,7 +674,9 @@
TEST_F(ClassLinkerTest, FindClassNested) {
ScopedObjectAccess soa(Thread::Current());
- SirtRef<mirror::ClassLoader> class_loader(soa.Self(), soa.Decode<mirror::ClassLoader*>(LoadDex("Nested")));
+ StackHandleScope<1> hs(soa.Self());
+ Handle<mirror::ClassLoader> class_loader(
+ hs.NewHandle(soa.Decode<mirror::ClassLoader*>(LoadDex("Nested"))));
mirror::Class* outer = class_linker_->FindClass(soa.Self(), "LNested;", class_loader);
ASSERT_TRUE(outer != NULL);
@@ -745,7 +750,9 @@
EXPECT_EQ(0U, JavaLangObject->NumStaticFields());
EXPECT_EQ(0U, kh.NumDirectInterfaces());
- SirtRef<mirror::ClassLoader> class_loader(soa.Self(), soa.Decode<mirror::ClassLoader*>(LoadDex("MyClass")));
+ StackHandleScope<1> hs(soa.Self());
+ Handle<mirror::ClassLoader> class_loader(
+ hs.NewHandle(soa.Decode<mirror::ClassLoader*>(LoadDex("MyClass"))));
AssertNonExistentClass("LMyClass;");
mirror::Class* MyClass = class_linker_->FindClass(soa.Self(), "LMyClass;", class_loader);
kh.ChangeClass(MyClass);
@@ -756,7 +763,7 @@
ASSERT_STREQ(kh.GetDescriptor(), "LMyClass;");
EXPECT_TRUE(MyClass->GetSuperClass() == JavaLangObject);
EXPECT_TRUE(MyClass->HasSuperClass());
- EXPECT_EQ(class_loader.get(), MyClass->GetClassLoader());
+ EXPECT_EQ(class_loader.Get(), MyClass->GetClassLoader());
EXPECT_EQ(mirror::Class::kStatusResolved, MyClass->GetStatus());
EXPECT_FALSE(MyClass->IsErroneous());
EXPECT_TRUE(MyClass->IsLoaded());
@@ -784,7 +791,7 @@
AssertArrayClass("[Ljava/lang/Object;", "Ljava/lang/Object;", NULL);
// synthesized on the fly
AssertArrayClass("[[C", "[C", NULL);
- AssertArrayClass("[[[LMyClass;", "[[LMyClass;", class_loader.get());
+ AssertArrayClass("[[[LMyClass;", "[[LMyClass;", class_loader.Get());
// or not available at all
AssertNonExistentClass("[[[[LNonExistentClass;");
}
@@ -813,27 +820,28 @@
TEST_F(ClassLinkerTest, ValidatePrimitiveArrayElementsOffset) {
ScopedObjectAccess soa(Thread::Current());
- SirtRef<mirror::LongArray> long_array(soa.Self(), mirror::LongArray::Alloc(soa.Self(), 0));
+ StackHandleScope<5> hs(soa.Self());
+ Handle<mirror::LongArray> long_array(hs.NewHandle(mirror::LongArray::Alloc(soa.Self(), 0)));
EXPECT_EQ(class_linker_->FindSystemClass(soa.Self(), "[J"), long_array->GetClass());
uintptr_t data_offset = reinterpret_cast<uintptr_t>(long_array->GetData());
EXPECT_TRUE(IsAligned<8>(data_offset)); // Longs require 8 byte alignment
- SirtRef<mirror::DoubleArray> double_array(soa.Self(), mirror::DoubleArray::Alloc(soa.Self(), 0));
+ Handle<mirror::DoubleArray> double_array(hs.NewHandle(mirror::DoubleArray::Alloc(soa.Self(), 0)));
EXPECT_EQ(class_linker_->FindSystemClass(soa.Self(), "[D"), double_array->GetClass());
data_offset = reinterpret_cast<uintptr_t>(double_array->GetData());
EXPECT_TRUE(IsAligned<8>(data_offset)); // Doubles require 8 byte alignment
- SirtRef<mirror::IntArray> int_array(soa.Self(), mirror::IntArray::Alloc(soa.Self(), 0));
+ Handle<mirror::IntArray> int_array(hs.NewHandle(mirror::IntArray::Alloc(soa.Self(), 0)));
EXPECT_EQ(class_linker_->FindSystemClass(soa.Self(), "[I"), int_array->GetClass());
data_offset = reinterpret_cast<uintptr_t>(int_array->GetData());
EXPECT_TRUE(IsAligned<4>(data_offset)); // Ints require 4 byte alignment
- SirtRef<mirror::CharArray> char_array(soa.Self(), mirror::CharArray::Alloc(soa.Self(), 0));
+ Handle<mirror::CharArray> char_array(hs.NewHandle(mirror::CharArray::Alloc(soa.Self(), 0)));
EXPECT_EQ(class_linker_->FindSystemClass(soa.Self(), "[C"), char_array->GetClass());
data_offset = reinterpret_cast<uintptr_t>(char_array->GetData());
EXPECT_TRUE(IsAligned<2>(data_offset)); // Chars require 2 byte alignment
- SirtRef<mirror::ShortArray> short_array(soa.Self(), mirror::ShortArray::Alloc(soa.Self(), 0));
+ Handle<mirror::ShortArray> short_array(hs.NewHandle(mirror::ShortArray::Alloc(soa.Self(), 0)));
EXPECT_EQ(class_linker_->FindSystemClass(soa.Self(), "[S"), short_array->GetClass());
data_offset = reinterpret_cast<uintptr_t>(short_array->GetData());
EXPECT_TRUE(IsAligned<2>(data_offset)); // Shorts require 2 byte alignment
@@ -845,7 +853,8 @@
// Validate that the "value" field is always the 0th field in each of java.lang's box classes.
// This lets UnboxPrimitive avoid searching for the field by name at runtime.
ScopedObjectAccess soa(Thread::Current());
- SirtRef<mirror::ClassLoader> class_loader(soa.Self(), nullptr);
+ StackHandleScope<1> hs(soa.Self());
+ auto class_loader(hs.NewHandle<mirror::ClassLoader>(nullptr));
mirror::Class* c;
c = class_linker_->FindClass(soa.Self(), "Ljava/lang/Boolean;", class_loader);
FieldHelper fh(c->GetIFields()->Get(0));
@@ -875,21 +884,25 @@
TEST_F(ClassLinkerTest, TwoClassLoadersOneClass) {
ScopedObjectAccess soa(Thread::Current());
- SirtRef<mirror::ClassLoader> class_loader_1(soa.Self(), soa.Decode<mirror::ClassLoader*>(LoadDex("MyClass")));
- SirtRef<mirror::ClassLoader> class_loader_2(soa.Self(), soa.Decode<mirror::ClassLoader*>(LoadDex("MyClass")));
+ StackHandleScope<2> hs(soa.Self());
+ Handle<mirror::ClassLoader> class_loader_1(
+ hs.NewHandle(soa.Decode<mirror::ClassLoader*>(LoadDex("MyClass"))));
+ Handle<mirror::ClassLoader> class_loader_2(
+ hs.NewHandle(soa.Decode<mirror::ClassLoader*>(LoadDex("MyClass"))));
mirror::Class* MyClass_1 = class_linker_->FindClass(soa.Self(), "LMyClass;", class_loader_1);
mirror::Class* MyClass_2 = class_linker_->FindClass(soa.Self(), "LMyClass;", class_loader_2);
- EXPECT_TRUE(MyClass_1 != NULL);
- EXPECT_TRUE(MyClass_2 != NULL);
+ EXPECT_TRUE(MyClass_1 != nullptr);
+ EXPECT_TRUE(MyClass_2 != nullptr);
EXPECT_NE(MyClass_1, MyClass_2);
}
TEST_F(ClassLinkerTest, StaticFields) {
ScopedObjectAccess soa(Thread::Current());
- SirtRef<mirror::ClassLoader> class_loader(soa.Self(),
- soa.Decode<mirror::ClassLoader*>(LoadDex("Statics")));
- SirtRef<mirror::Class> statics(soa.Self(), class_linker_->FindClass(soa.Self(), "LStatics;",
- class_loader));
+ StackHandleScope<2> hs(soa.Self());
+ Handle<mirror::ClassLoader> class_loader(
+ hs.NewHandle(soa.Decode<mirror::ClassLoader*>(LoadDex("Statics"))));
+ Handle<mirror::Class> statics(
+ hs.NewHandle(class_linker_->FindClass(soa.Self(), "LStatics;", class_loader)));
class_linker_->EnsureInitialized(statics, true, true);
// Static final primitives that are initialized by a compile-time constant
@@ -904,74 +917,76 @@
FieldHelper fh(s0);
EXPECT_STREQ(ClassHelper(s0->GetClass()).GetDescriptor(), "Ljava/lang/reflect/ArtField;");
EXPECT_TRUE(fh.GetTypeAsPrimitiveType() == Primitive::kPrimBoolean);
- EXPECT_EQ(true, s0->GetBoolean(statics.get()));
- s0->SetBoolean<false>(statics.get(), false);
+ EXPECT_EQ(true, s0->GetBoolean(statics.Get()));
+ s0->SetBoolean<false>(statics.Get(), false);
mirror::ArtField* s1 = statics->FindStaticField("s1", "B");
fh.ChangeField(s1);
EXPECT_TRUE(fh.GetTypeAsPrimitiveType() == Primitive::kPrimByte);
- EXPECT_EQ(5, s1->GetByte(statics.get()));
- s1->SetByte<false>(statics.get(), 6);
+ EXPECT_EQ(5, s1->GetByte(statics.Get()));
+ s1->SetByte<false>(statics.Get(), 6);
mirror::ArtField* s2 = statics->FindStaticField("s2", "C");
fh.ChangeField(s2);
EXPECT_TRUE(fh.GetTypeAsPrimitiveType() == Primitive::kPrimChar);
- EXPECT_EQ('a', s2->GetChar(statics.get()));
- s2->SetChar<false>(statics.get(), 'b');
+ EXPECT_EQ('a', s2->GetChar(statics.Get()));
+ s2->SetChar<false>(statics.Get(), 'b');
mirror::ArtField* s3 = statics->FindStaticField("s3", "S");
fh.ChangeField(s3);
EXPECT_TRUE(fh.GetTypeAsPrimitiveType() == Primitive::kPrimShort);
- EXPECT_EQ(-536, s3->GetShort(statics.get()));
- s3->SetShort<false>(statics.get(), -535);
+ EXPECT_EQ(-536, s3->GetShort(statics.Get()));
+ s3->SetShort<false>(statics.Get(), -535);
mirror::ArtField* s4 = statics->FindStaticField("s4", "I");
fh.ChangeField(s4);
EXPECT_TRUE(fh.GetTypeAsPrimitiveType() == Primitive::kPrimInt);
- EXPECT_EQ(2000000000, s4->GetInt(statics.get()));
- s4->SetInt<false>(statics.get(), 2000000001);
+ EXPECT_EQ(2000000000, s4->GetInt(statics.Get()));
+ s4->SetInt<false>(statics.Get(), 2000000001);
mirror::ArtField* s5 = statics->FindStaticField("s5", "J");
fh.ChangeField(s5);
EXPECT_TRUE(fh.GetTypeAsPrimitiveType() == Primitive::kPrimLong);
- EXPECT_EQ(0x1234567890abcdefLL, s5->GetLong(statics.get()));
- s5->SetLong<false>(statics.get(), INT64_C(0x34567890abcdef12));
+ EXPECT_EQ(0x1234567890abcdefLL, s5->GetLong(statics.Get()));
+ s5->SetLong<false>(statics.Get(), INT64_C(0x34567890abcdef12));
mirror::ArtField* s6 = statics->FindStaticField("s6", "F");
fh.ChangeField(s6);
EXPECT_TRUE(fh.GetTypeAsPrimitiveType() == Primitive::kPrimFloat);
- EXPECT_EQ(0.5, s6->GetFloat(statics.get()));
- s6->SetFloat<false>(statics.get(), 0.75);
+ EXPECT_EQ(0.5, s6->GetFloat(statics.Get()));
+ s6->SetFloat<false>(statics.Get(), 0.75);
mirror::ArtField* s7 = statics->FindStaticField("s7", "D");
fh.ChangeField(s7);
EXPECT_TRUE(fh.GetTypeAsPrimitiveType() == Primitive::kPrimDouble);
- EXPECT_EQ(16777217, s7->GetDouble(statics.get()));
- s7->SetDouble<false>(statics.get(), 16777219);
+ EXPECT_EQ(16777217, s7->GetDouble(statics.Get()));
+ s7->SetDouble<false>(statics.Get(), 16777219);
mirror::ArtField* s8 = statics->FindStaticField("s8", "Ljava/lang/String;");
fh.ChangeField(s8);
EXPECT_TRUE(fh.GetTypeAsPrimitiveType() == Primitive::kPrimNot);
- EXPECT_TRUE(s8->GetObject(statics.get())->AsString()->Equals("android"));
+ EXPECT_TRUE(s8->GetObject(statics.Get())->AsString()->Equals("android"));
s8->SetObject<false>(s8->GetDeclaringClass(),
mirror::String::AllocFromModifiedUtf8(soa.Self(), "robot"));
// TODO: Remove EXPECT_FALSE when GCC can handle EXPECT_EQ
// http://code.google.com/p/googletest/issues/detail?id=322
- EXPECT_FALSE(s0->GetBoolean(statics.get()));
- EXPECT_EQ(6, s1->GetByte(statics.get()));
- EXPECT_EQ('b', s2->GetChar(statics.get()));
- EXPECT_EQ(-535, s3->GetShort(statics.get()));
- EXPECT_EQ(2000000001, s4->GetInt(statics.get()));
- EXPECT_EQ(INT64_C(0x34567890abcdef12), s5->GetLong(statics.get()));
- EXPECT_EQ(0.75, s6->GetFloat(statics.get()));
- EXPECT_EQ(16777219, s7->GetDouble(statics.get()));
- EXPECT_TRUE(s8->GetObject(statics.get())->AsString()->Equals("robot"));
+ EXPECT_FALSE(s0->GetBoolean(statics.Get()));
+ EXPECT_EQ(6, s1->GetByte(statics.Get()));
+ EXPECT_EQ('b', s2->GetChar(statics.Get()));
+ EXPECT_EQ(-535, s3->GetShort(statics.Get()));
+ EXPECT_EQ(2000000001, s4->GetInt(statics.Get()));
+ EXPECT_EQ(INT64_C(0x34567890abcdef12), s5->GetLong(statics.Get()));
+ EXPECT_EQ(0.75, s6->GetFloat(statics.Get()));
+ EXPECT_EQ(16777219, s7->GetDouble(statics.Get()));
+ EXPECT_TRUE(s8->GetObject(statics.Get())->AsString()->Equals("robot"));
}
TEST_F(ClassLinkerTest, Interfaces) {
ScopedObjectAccess soa(Thread::Current());
- SirtRef<mirror::ClassLoader> class_loader(soa.Self(), soa.Decode<mirror::ClassLoader*>(LoadDex("Interfaces")));
+ StackHandleScope<1> hs(soa.Self());
+ Handle<mirror::ClassLoader> class_loader(
+ hs.NewHandle(soa.Decode<mirror::ClassLoader*>(LoadDex("Interfaces"))));
mirror::Class* I = class_linker_->FindClass(soa.Self(), "LInterfaces$I;", class_loader);
mirror::Class* J = class_linker_->FindClass(soa.Self(), "LInterfaces$J;", class_loader);
mirror::Class* K = class_linker_->FindClass(soa.Self(), "LInterfaces$K;", class_loader);
@@ -1032,7 +1047,9 @@
ScopedObjectAccess soa(Thread::Current());
jobject jclass_loader = LoadDex("StaticsFromCode");
- SirtRef<mirror::ClassLoader> class_loader(soa.Self(), soa.Decode<mirror::ClassLoader*>(jclass_loader));
+ StackHandleScope<1> hs(soa.Self());
+ Handle<mirror::ClassLoader> class_loader(
+ hs.NewHandle(soa.Decode<mirror::ClassLoader*>(jclass_loader)));
const DexFile* dex_file = Runtime::Current()->GetCompileTimeClassPath(jclass_loader)[0];
CHECK(dex_file != NULL);
mirror::Class* klass = class_linker_->FindClass(soa.Self(), "LStaticsFromCode;", class_loader);