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/interpreter/unstarted_runtime.cc b/runtime/interpreter/unstarted_runtime.cc
index 1f473e4..793260d 100644
--- a/runtime/interpreter/unstarted_runtime.cc
+++ b/runtime/interpreter/unstarted_runtime.cc
@@ -300,11 +300,25 @@
PrettyDescriptor(klass).c_str());
return;
}
- if (Runtime::Current()->IsActiveTransaction()) {
- result->SetL(mirror::Field::CreateFromArtField<true>(self, found, true));
+ Runtime* runtime = Runtime::Current();
+ size_t pointer_size = runtime->GetClassLinker()->GetImagePointerSize();
+ mirror::Field* field;
+ if (runtime->IsActiveTransaction()) {
+ if (pointer_size == 8) {
+ field = mirror::Field::CreateFromArtField<8U, true>(self, found, true);
+ } else {
+ DCHECK_EQ(pointer_size, 4U);
+ field = mirror::Field::CreateFromArtField<4U, true>(self, found, true);
+ }
} else {
- result->SetL(mirror::Field::CreateFromArtField<false>(self, found, true));
+ if (pointer_size == 8) {
+ field = mirror::Field::CreateFromArtField<8U, false>(self, found, true);
+ } else {
+ DCHECK_EQ(pointer_size, 4U);
+ field = mirror::Field::CreateFromArtField<4U, false>(self, found, true);
+ }
}
+ result->SetL(field);
}
// This is required for Enum(Set) code, as that uses reflection to inspect enum classes.
@@ -319,11 +333,26 @@
mirror::String* name = shadow_frame->GetVRegReference(arg_offset + 1)->AsString();
mirror::ObjectArray<mirror::Class>* args =
shadow_frame->GetVRegReference(arg_offset + 2)->AsObjectArray<mirror::Class>();
- if (Runtime::Current()->IsActiveTransaction()) {
- result->SetL(mirror::Class::GetDeclaredMethodInternal<true>(self, klass, name, args));
+ Runtime* runtime = Runtime::Current();
+ bool transaction = runtime->IsActiveTransaction();
+ size_t pointer_size = runtime->GetClassLinker()->GetImagePointerSize();
+ mirror::Method* method;
+ if (transaction) {
+ if (pointer_size == 8U) {
+ method = mirror::Class::GetDeclaredMethodInternal<8U, true>(self, klass, name, args);
+ } else {
+ DCHECK_EQ(pointer_size, 4U);
+ method = mirror::Class::GetDeclaredMethodInternal<4U, true>(self, klass, name, args);
+ }
} else {
- result->SetL(mirror::Class::GetDeclaredMethodInternal<false>(self, klass, name, args));
+ if (pointer_size == 8U) {
+ method = mirror::Class::GetDeclaredMethodInternal<8U, false>(self, klass, name, args);
+ } else {
+ DCHECK_EQ(pointer_size, 4U);
+ method = mirror::Class::GetDeclaredMethodInternal<4U, false>(self, klass, name, args);
+ }
}
+ result->SetL(method);
}
// Special managed code cut-out to allow constructor lookup in a un-started runtime.
@@ -336,11 +365,26 @@
}
mirror::ObjectArray<mirror::Class>* args =
shadow_frame->GetVRegReference(arg_offset + 1)->AsObjectArray<mirror::Class>();
- if (Runtime::Current()->IsActiveTransaction()) {
- result->SetL(mirror::Class::GetDeclaredConstructorInternal<true>(self, klass, args));
+ Runtime* runtime = Runtime::Current();
+ bool transaction = runtime->IsActiveTransaction();
+ size_t pointer_size = runtime->GetClassLinker()->GetImagePointerSize();
+ mirror::Constructor* constructor;
+ if (transaction) {
+ if (pointer_size == 8U) {
+ constructor = mirror::Class::GetDeclaredConstructorInternal<8U, true>(self, klass, args);
+ } else {
+ DCHECK_EQ(pointer_size, 4U);
+ constructor = mirror::Class::GetDeclaredConstructorInternal<4U, true>(self, klass, args);
+ }
} else {
- result->SetL(mirror::Class::GetDeclaredConstructorInternal<false>(self, klass, args));
+ if (pointer_size == 8U) {
+ constructor = mirror::Class::GetDeclaredConstructorInternal<8U, false>(self, klass, args);
+ } else {
+ DCHECK_EQ(pointer_size, 4U);
+ constructor = mirror::Class::GetDeclaredConstructorInternal<4U, false>(self, klass, args);
+ }
}
+ result->SetL(constructor);
}
void UnstartedRuntime::UnstartedClassGetEnclosingClass(