summaryrefslogtreecommitdiff
path: root/runtime/class_linker.cc
diff options
context:
space:
mode:
author Nicolas Geoffray <ngeoffray@google.com> 2021-03-10 15:09:19 +0000
committer Nicolas Geoffray <ngeoffray@google.com> 2021-03-24 16:47:38 +0000
commit43c9cd7938a53265ea9899a604b409ce070cc2c5 (patch)
treedb084fcc115d6a68de25662bf1a5fae030bcf152 /runtime/class_linker.cc
parent443fc8962db219177c34cd047d2071b5ee775468 (diff)
Improve nterp -> compiled code transitions.
Use an unused bit in the access flags of an ArtMethod (0x00200000) to store the information a method only takes ints or references and returns an int, a reference, or a long. This avoids the need to fetch the shorty in nterp when doing a call. Test: test.py Test: 821-many-args Bug: 112676029 Change-Id: Ie657ccf69c17c1097dc2a97f18e3093ef3be391b
Diffstat (limited to 'runtime/class_linker.cc')
-rw-r--r--runtime/class_linker.cc35
1 files changed, 24 insertions, 11 deletions
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index 2040263cc6..745e7cf73f 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -3838,21 +3838,34 @@ void ClassLinker::LoadMethod(const DexFile& dex_file,
} else {
dst->SetCodeItem(dst->GetDexFile()->GetCodeItem(method.GetCodeItemOffset()));
}
- bool has_all_references = true;
- const char* shorty = dst->GetShorty();
- for (size_t i = 1, e = strlen(shorty); i < e; ++i) {
- if (shorty[i] != 'L') {
- has_all_references = false;
- break;
- }
- }
- if (has_all_references) {
- dst->SetNterpEntryPointFastPathFlag();
- }
} else {
dst->SetDataPtrSize(nullptr, image_pointer_size_);
DCHECK_EQ(method.GetCodeItemOffset(), 0u);
}
+
+ // Set optimization flags related to the shorty.
+ const char* shorty = dst->GetShorty();
+ bool all_parameters_are_reference = true;
+ bool all_parameters_are_reference_or_int = true;
+ bool return_type_is_fp = (shorty[0] == 'F' || shorty[0] == 'D');
+
+ for (size_t i = 1, e = strlen(shorty); i < e; ++i) {
+ if (shorty[i] != 'L') {
+ all_parameters_are_reference = false;
+ if (shorty[i] == 'F' || shorty[i] == 'D' || shorty[i] == 'J') {
+ all_parameters_are_reference_or_int = false;
+ break;
+ }
+ }
+ }
+
+ if (!dst->IsNative() && all_parameters_are_reference) {
+ dst->SetNterpEntryPointFastPathFlag();
+ }
+
+ if (!return_type_is_fp && all_parameters_are_reference_or_int) {
+ dst->SetNterpInvokeFastPathFlag();
+ }
}
void ClassLinker::AppendToBootClassPath(Thread* self, const DexFile* dex_file) {