ART: Add pointer-size template to some reflection functions
The unstarted runtime may run code for a different pointer size,
even when no transaction is active (e.g., during startup). To
retain performance when the runtime is up and executing under
normal conditions, add a template parameter and use sizeof(void*)
in places where it is adequate.
For maintainability, it is necessary to drop the default for
the transaction template parameter. Implicit conversions from
bool to size_t may lead to incorrect code and hard to diagnose
problems. So instead ensure that all callers must give all
template parameter values.
Test: m test-art-host
Change-Id: I3076883422c8553ede4de5642409c5684a5a9aa8
diff --git a/runtime/mirror/abstract_method.cc b/runtime/mirror/abstract_method.cc
index 5a07dee..ef39132 100644
--- a/runtime/mirror/abstract_method.cc
+++ b/runtime/mirror/abstract_method.cc
@@ -21,12 +21,9 @@
namespace art {
namespace mirror {
-template <bool kTransactionActive>
+template <size_t kPointerSize, bool kTransactionActive>
bool AbstractMethod::CreateFromArtMethod(ArtMethod* method) {
- auto* interface_method = method->GetInterfaceMethodIfProxy(
- kTransactionActive
- ? Runtime::Current()->GetClassLinker()->GetImagePointerSize()
- : sizeof(void*));
+ auto* interface_method = method->GetInterfaceMethodIfProxy(kPointerSize);
SetArtMethod<kTransactionActive>(method);
SetFieldObject<kTransactionActive>(DeclaringClassOffset(), method->GetDeclaringClass());
SetFieldObject<kTransactionActive>(
@@ -36,8 +33,10 @@
return true;
}
-template bool AbstractMethod::CreateFromArtMethod<false>(ArtMethod* method);
-template bool AbstractMethod::CreateFromArtMethod<true>(ArtMethod* method);
+template bool AbstractMethod::CreateFromArtMethod<4U, false>(ArtMethod* method);
+template bool AbstractMethod::CreateFromArtMethod<4U, true>(ArtMethod* method);
+template bool AbstractMethod::CreateFromArtMethod<8U, false>(ArtMethod* method);
+template bool AbstractMethod::CreateFromArtMethod<8U, true>(ArtMethod* method);
ArtMethod* AbstractMethod::GetArtMethod() {
return reinterpret_cast<ArtMethod*>(GetField64(ArtMethodOffset()));
diff --git a/runtime/mirror/abstract_method.h b/runtime/mirror/abstract_method.h
index a39f94d..936b14c 100644
--- a/runtime/mirror/abstract_method.h
+++ b/runtime/mirror/abstract_method.h
@@ -34,7 +34,7 @@
class MANAGED AbstractMethod : public AccessibleObject {
public:
// Called from Constructor::CreateFromArtMethod, Method::CreateFromArtMethod.
- template <bool kTransactionActive = false>
+ template <size_t kPointerSize, bool kTransactionActive>
bool CreateFromArtMethod(ArtMethod* method) SHARED_REQUIRES(Locks::mutator_lock_)
REQUIRES(!Roles::uninterruptible_);
diff --git a/runtime/mirror/class.cc b/runtime/mirror/class.cc
index 1c31c57..375cb2f 100644
--- a/runtime/mirror/class.cc
+++ b/runtime/mirror/class.cc
@@ -1053,7 +1053,7 @@
return (type_id == nullptr) ? DexFile::kDexNoIndex : dex_file.GetIndexForTypeId(*type_id);
}
-template <bool kTransactionActive>
+template <size_t kPointerSize, bool kTransactionActive>
mirror::Method* Class::GetDeclaredMethodInternal(Thread* self,
mirror::Class* klass,
mirror::String* name,
@@ -1074,11 +1074,8 @@
auto h_args = hs.NewHandle(args);
Handle<mirror::Class> h_klass = hs.NewHandle(klass);
ArtMethod* result = nullptr;
- const size_t pointer_size = kTransactionActive
- ? Runtime::Current()->GetClassLinker()->GetImagePointerSize()
- : sizeof(void*);
- for (auto& m : h_klass->GetDeclaredVirtualMethods(pointer_size)) {
- auto* np_method = m.GetInterfaceMethodIfProxy(pointer_size);
+ for (auto& m : h_klass->GetDeclaredVirtualMethods(kPointerSize)) {
+ auto* np_method = m.GetInterfaceMethodIfProxy(kPointerSize);
// May cause thread suspension.
mirror::String* np_name = np_method->GetNameAsString(self);
if (!np_name->Equals(h_method_name.Get()) || !np_method->EqualParameters(h_args)) {
@@ -1089,19 +1086,19 @@
}
auto modifiers = m.GetAccessFlags();
if ((modifiers & kSkipModifiers) == 0) {
- return mirror::Method::CreateFromArtMethod<kTransactionActive>(self, &m);
+ return mirror::Method::CreateFromArtMethod<kPointerSize, kTransactionActive>(self, &m);
}
if ((modifiers & kAccMiranda) == 0) {
result = &m; // Remember as potential result if it's not a miranda method.
}
}
if (result == nullptr) {
- for (auto& m : h_klass->GetDirectMethods(pointer_size)) {
+ for (auto& m : h_klass->GetDirectMethods(kPointerSize)) {
auto modifiers = m.GetAccessFlags();
if ((modifiers & kAccConstructor) != 0) {
continue;
}
- auto* np_method = m.GetInterfaceMethodIfProxy(pointer_size);
+ auto* np_method = m.GetInterfaceMethodIfProxy(kPointerSize);
// May cause thread suspension.
mirror::String* np_name = np_method->GetNameAsString(self);
if (np_name == nullptr) {
@@ -1115,50 +1112,69 @@
continue;
}
if ((modifiers & kSkipModifiers) == 0) {
- return mirror::Method::CreateFromArtMethod<kTransactionActive>(self, &m);
+ return mirror::Method::CreateFromArtMethod<kPointerSize, kTransactionActive>(self, &m);
}
// Direct methods cannot be miranda methods, so this potential result must be synthetic.
result = &m;
}
}
return result != nullptr
- ? mirror::Method::CreateFromArtMethod<kTransactionActive>(self, result)
+ ? mirror::Method::CreateFromArtMethod<kPointerSize, kTransactionActive>(self, result)
: nullptr;
}
template
-mirror::Method* Class::GetDeclaredMethodInternal<false>(Thread* self,
- mirror::Class* klass,
- mirror::String* name,
- mirror::ObjectArray<mirror::Class>* args);
+mirror::Method* Class::GetDeclaredMethodInternal<4U, false>(
+ Thread* self,
+ mirror::Class* klass,
+ mirror::String* name,
+ mirror::ObjectArray<mirror::Class>* args);
template
-mirror::Method* Class::GetDeclaredMethodInternal<true>(Thread* self,
- mirror::Class* klass,
- mirror::String* name,
- mirror::ObjectArray<mirror::Class>* args);
+mirror::Method* Class::GetDeclaredMethodInternal<4U, true>(
+ Thread* self,
+ mirror::Class* klass,
+ mirror::String* name,
+ mirror::ObjectArray<mirror::Class>* args);
+template
+mirror::Method* Class::GetDeclaredMethodInternal<8U, false>(
+ Thread* self,
+ mirror::Class* klass,
+ mirror::String* name,
+ mirror::ObjectArray<mirror::Class>* args);
+template
+mirror::Method* Class::GetDeclaredMethodInternal<8U, true>(
+ Thread* self,
+ mirror::Class* klass,
+ mirror::String* name,
+ mirror::ObjectArray<mirror::Class>* args);
-template <bool kTransactionActive>
+template <size_t kPointerSize, bool kTransactionActive>
mirror::Constructor* Class::GetDeclaredConstructorInternal(
Thread* self,
mirror::Class* klass,
mirror::ObjectArray<mirror::Class>* args) {
StackHandleScope<1> hs(self);
- const size_t pointer_size = kTransactionActive
- ? Runtime::Current()->GetClassLinker()->GetImagePointerSize()
- : sizeof(void*);
- ArtMethod* result = klass->GetDeclaredConstructor(self, hs.NewHandle(args), pointer_size);
+ ArtMethod* result = klass->GetDeclaredConstructor(self, hs.NewHandle(args), kPointerSize);
return result != nullptr
- ? mirror::Constructor::CreateFromArtMethod<kTransactionActive>(self, result)
+ ? mirror::Constructor::CreateFromArtMethod<kPointerSize, kTransactionActive>(self, result)
: nullptr;
}
// mirror::Constructor::CreateFromArtMethod<kTransactionActive>(self, result)
-template mirror::Constructor* Class::GetDeclaredConstructorInternal<false>(
+template mirror::Constructor* Class::GetDeclaredConstructorInternal<4U, false>(
Thread* self,
mirror::Class* klass,
mirror::ObjectArray<mirror::Class>* args);
-template mirror::Constructor* Class::GetDeclaredConstructorInternal<true>(
+template mirror::Constructor* Class::GetDeclaredConstructorInternal<4U, true>(
+ Thread* self,
+ mirror::Class* klass,
+ mirror::ObjectArray<mirror::Class>* args);
+template mirror::Constructor* Class::GetDeclaredConstructorInternal<8U, false>(
+ Thread* self,
+ mirror::Class* klass,
+ mirror::ObjectArray<mirror::Class>* args);
+template mirror::Constructor* Class::GetDeclaredConstructorInternal<8U, true>(
Thread* self,
mirror::Class* klass,
mirror::ObjectArray<mirror::Class>* args);
diff --git a/runtime/mirror/class.h b/runtime/mirror/class.h
index 9be9f01..32ed337 100644
--- a/runtime/mirror/class.h
+++ b/runtime/mirror/class.h
@@ -754,13 +754,13 @@
size_t pointer_size)
SHARED_REQUIRES(Locks::mutator_lock_);
- template <bool kTransactionActive = false>
+ template <size_t kPointerSize, bool kTransactionActive>
static Method* GetDeclaredMethodInternal(Thread* self,
mirror::Class* klass,
mirror::String* name,
mirror::ObjectArray<mirror::Class>* args)
SHARED_REQUIRES(Locks::mutator_lock_);
- template <bool kTransactionActive = false>
+ template <size_t kPointerSize, bool kTransactionActive>
static Constructor* GetDeclaredConstructorInternal(Thread* self,
mirror::Class* klass,
mirror::ObjectArray<mirror::Class>* args)
diff --git a/runtime/mirror/field-inl.h b/runtime/mirror/field-inl.h
index 8a0daec..4183476 100644
--- a/runtime/mirror/field-inl.h
+++ b/runtime/mirror/field-inl.h
@@ -27,7 +27,7 @@
namespace mirror {
-template <bool kTransactionActive>
+template <size_t kPointerSize, bool kTransactionActive>
inline mirror::Field* Field::CreateFromArtField(Thread* self, ArtField* field,
bool force_resolve) {
StackHandleScope<2> hs(self);
@@ -54,10 +54,8 @@
self->AssertPendingOOMException();
return nullptr;
}
- const auto pointer_size = kTransactionActive ?
- Runtime::Current()->GetClassLinker()->GetImagePointerSize() : sizeof(void*);
auto dex_field_index = field->GetDexFieldIndex();
- auto* resolved_field = field->GetDexCache()->GetResolvedField(dex_field_index, pointer_size);
+ auto* resolved_field = field->GetDexCache()->GetResolvedField(dex_field_index, kPointerSize);
if (field->GetDeclaringClass()->IsProxyClass()) {
DCHECK(field->IsStatic());
DCHECK_LT(dex_field_index, 2U);
@@ -70,7 +68,7 @@
} else {
// We rely on the field being resolved so that we can back to the ArtField
// (i.e. FromReflectedMethod).
- field->GetDexCache()->SetResolvedField(dex_field_index, field, pointer_size);
+ field->GetDexCache()->SetResolvedField(dex_field_index, field, kPointerSize);
}
}
ret->SetType<kTransactionActive>(type.Get());
diff --git a/runtime/mirror/field.h b/runtime/mirror/field.h
index edaddbd..2bd6132 100644
--- a/runtime/mirror/field.h
+++ b/runtime/mirror/field.h
@@ -92,7 +92,7 @@
// Slow, try to use only for PrettyField and such.
ArtField* GetArtField() SHARED_REQUIRES(Locks::mutator_lock_);
- template <bool kTransactionActive = false>
+ template <size_t kPointerSize, bool kTransactionActive = false>
static mirror::Field* CreateFromArtField(Thread* self, ArtField* field,
bool force_resolve)
SHARED_REQUIRES(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_);
diff --git a/runtime/mirror/method.cc b/runtime/mirror/method.cc
index 9838b71..3cc70e1 100644
--- a/runtime/mirror/method.cc
+++ b/runtime/mirror/method.cc
@@ -51,18 +51,21 @@
array_class_ = GcRoot<Class>(nullptr);
}
-template <bool kTransactionActive>
+template <size_t kPointerSize, bool kTransactionActive>
Method* Method::CreateFromArtMethod(Thread* self, ArtMethod* method) {
DCHECK(!method->IsConstructor()) << PrettyMethod(method);
auto* ret = down_cast<Method*>(StaticClass()->AllocObject(self));
if (LIKELY(ret != nullptr)) {
- static_cast<AbstractMethod*>(ret)->CreateFromArtMethod<kTransactionActive>(method);
+ static_cast<AbstractMethod*>(ret)->
+ CreateFromArtMethod<kPointerSize, kTransactionActive>(method);
}
return ret;
}
-template Method* Method::CreateFromArtMethod<false>(Thread* self, ArtMethod* method);
-template Method* Method::CreateFromArtMethod<true>(Thread* self, ArtMethod* method);
+template Method* Method::CreateFromArtMethod<4U, false>(Thread* self, ArtMethod* method);
+template Method* Method::CreateFromArtMethod<4U, true>(Thread* self, ArtMethod* method);
+template Method* Method::CreateFromArtMethod<8U, false>(Thread* self, ArtMethod* method);
+template Method* Method::CreateFromArtMethod<8U, true>(Thread* self, ArtMethod* method);
void Method::VisitRoots(RootVisitor* visitor) {
static_class_.VisitRootIfNonNull(visitor, RootInfo(kRootStickyClass));
@@ -96,18 +99,21 @@
array_class_.VisitRootIfNonNull(visitor, RootInfo(kRootStickyClass));
}
-template <bool kTransactionActive>
+template <size_t kPointerSize, bool kTransactionActive>
Constructor* Constructor::CreateFromArtMethod(Thread* self, ArtMethod* method) {
DCHECK(method->IsConstructor()) << PrettyMethod(method);
auto* ret = down_cast<Constructor*>(StaticClass()->AllocObject(self));
if (LIKELY(ret != nullptr)) {
- static_cast<AbstractMethod*>(ret)->CreateFromArtMethod<kTransactionActive>(method);
+ static_cast<AbstractMethod*>(ret)->
+ CreateFromArtMethod<kPointerSize, kTransactionActive>(method);
}
return ret;
}
-template Constructor* Constructor::CreateFromArtMethod<false>(Thread* self, ArtMethod* method);
-template Constructor* Constructor::CreateFromArtMethod<true>(Thread* self, ArtMethod* method);
+template Constructor* Constructor::CreateFromArtMethod<4U, false>(Thread* self, ArtMethod* method);
+template Constructor* Constructor::CreateFromArtMethod<4U, true>(Thread* self, ArtMethod* method);
+template Constructor* Constructor::CreateFromArtMethod<8U, false>(Thread* self, ArtMethod* method);
+template Constructor* Constructor::CreateFromArtMethod<8U, true>(Thread* self, ArtMethod* method);
} // namespace mirror
} // namespace art
diff --git a/runtime/mirror/method.h b/runtime/mirror/method.h
index 0b56964..ecd6a74 100644
--- a/runtime/mirror/method.h
+++ b/runtime/mirror/method.h
@@ -28,7 +28,7 @@
// C++ mirror of java.lang.reflect.Method.
class MANAGED Method : public AbstractMethod {
public:
- template <bool kTransactionActive = false>
+ template <size_t kPointerSize, bool kTransactionActive>
static Method* CreateFromArtMethod(Thread* self, ArtMethod* method)
SHARED_REQUIRES(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_);
@@ -60,7 +60,7 @@
// C++ mirror of java.lang.reflect.Constructor.
class MANAGED Constructor: public AbstractMethod {
public:
- template <bool kTransactionActive = false>
+ template <size_t kPointerSize, bool kTransactionActive>
static Constructor* CreateFromArtMethod(Thread* self, ArtMethod* method)
SHARED_REQUIRES(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_);