diff options
author | 2021-03-10 15:09:19 +0000 | |
---|---|---|
committer | 2021-03-24 16:47:38 +0000 | |
commit | 43c9cd7938a53265ea9899a604b409ce070cc2c5 (patch) | |
tree | db084fcc115d6a68de25662bf1a5fae030bcf152 /runtime/class_linker.cc | |
parent | 443fc8962db219177c34cd047d2071b5ee775468 (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.cc | 35 |
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) { |