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/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);