Increment hotness in nterp when doing lookups.
Test: test.py
Test: google/perf/app-transition/app-transition-to-recents
Bug: 112676029
Bug: 157402634
Change-Id: Ibe08720b442c5050062db1104be2d3a62641e629
diff --git a/runtime/interpreter/mterp/nterp.cc b/runtime/interpreter/mterp/nterp.cc
index 2eb3650..95b4243 100644
--- a/runtime/interpreter/mterp/nterp.cc
+++ b/runtime/interpreter/mterp/nterp.cc
@@ -17,7 +17,7 @@
/*
* Mterp entry point and support functions.
*/
-#include "mterp.h"
+#include "nterp.h"
#include "base/quasi_atomic.h"
#include "dex/dex_instruction_utils.h"
@@ -45,7 +45,7 @@
return method->SkipAccessChecks() &&
!method->IsNative() &&
method->GetDexFile()->IsStandardDexFile() &&
- NterpGetFrameSize(method) < kMaxNterpFrame;
+ NterpGetFrameSize(method) < kNterpMaxFrame;
}
const void* GetNterpEntryPoint() {
@@ -71,6 +71,24 @@
}
}
+inline void UpdateHotness(ArtMethod* method) REQUIRES_SHARED(Locks::mutator_lock_) {
+ // The hotness we will add to a method when we perform a
+ // field/method/class/string lookup.
+ constexpr uint16_t kNterpHotnessLookup = 0xff;
+
+ // Convert to uint32_t to handle uint16_t overflow.
+ uint32_t counter = method->GetCounter();
+ uint32_t new_counter = counter + kNterpHotnessLookup;
+ if ((new_counter & kNterpHotnessMask) == 0) {
+ // Let the nterp code actually call the compilation: we want to make sure
+ // there's at least a second execution of the method or a back-edge to avoid
+ // compiling straightline initialization methods.
+ method->SetCounter(kNterpHotnessMask - 1);
+ } else {
+ method->SetCounter(new_counter);
+ }
+}
+
template<typename T>
inline void UpdateCache(Thread* self, uint16_t* dex_pc_ptr, T value) {
DCHECK(kUseReadBarrier) << "Nterp only works with read barriers";
@@ -129,6 +147,7 @@
extern "C" size_t NterpGetMethod(Thread* self, ArtMethod* caller, uint16_t* dex_pc_ptr)
REQUIRES_SHARED(Locks::mutator_lock_) {
+ UpdateHotness(caller);
const Instruction* inst = Instruction::At(dex_pc_ptr);
InvokeType invoke_type = kStatic;
uint16_t method_index = 0;
@@ -320,6 +339,7 @@
extern "C" size_t NterpGetStaticField(Thread* self, ArtMethod* caller, uint16_t* dex_pc_ptr)
REQUIRES_SHARED(Locks::mutator_lock_) {
+ UpdateHotness(caller);
const Instruction* inst = Instruction::At(dex_pc_ptr);
uint16_t field_index = inst->VRegB_21c();
ClassLinker* const class_linker = Runtime::Current()->GetClassLinker();
@@ -360,6 +380,7 @@
ArtMethod* caller,
uint16_t* dex_pc_ptr)
REQUIRES_SHARED(Locks::mutator_lock_) {
+ UpdateHotness(caller);
const Instruction* inst = Instruction::At(dex_pc_ptr);
uint16_t field_index = inst->VRegC_22c();
ClassLinker* const class_linker = Runtime::Current()->GetClassLinker();
@@ -387,6 +408,7 @@
ArtMethod* caller,
uint16_t* dex_pc_ptr)
REQUIRES_SHARED(Locks::mutator_lock_) {
+ UpdateHotness(caller);
const Instruction* inst = Instruction::At(dex_pc_ptr);
dex::TypeIndex index;
switch (inst->Opcode()) {
@@ -446,6 +468,7 @@
switch (inst->Opcode()) {
case Instruction::CONST_STRING:
case Instruction::CONST_STRING_JUMBO: {
+ UpdateHotness(caller);
dex::StringIndex string_index(
(inst->Opcode() == Instruction::CONST_STRING)
? inst->VRegB_21c()