Add weight to compiled/interpreter transitions.
Also:
- Cleanup logging.
- Check ArtMethod status before adding compilation requests.
- Don't request osr compilation if we know AddSamples does not come
from a back edge.
Bug: 27865109
Change-Id: I84512f7d957b61ce2458360ed430adb151830278
diff --git a/runtime/interpreter/interpreter.cc b/runtime/interpreter/interpreter.cc
index a432782..97dbe5d 100644
--- a/runtime/interpreter/interpreter.cc
+++ b/runtime/interpreter/interpreter.cc
@@ -292,7 +292,7 @@
// Pop the shadow frame before calling into compiled code.
self->PopShadowFrame();
- ArtInterpreterToCompiledCodeBridge(self, code_item, &shadow_frame, &result);
+ ArtInterpreterToCompiledCodeBridge(self, nullptr, code_item, &shadow_frame, &result);
// Push the shadow frame back as the caller will expect it.
self->PushShadowFrame(&shadow_frame);
@@ -535,6 +535,10 @@
return JValue();
}
+ jit::Jit* jit = Runtime::Current()->GetJit();
+ if (jit != nullptr) {
+ jit->NotifyCompiledCodeToInterpreterTransition(self, shadow_frame->GetMethod());
+ }
return Execute(self, code_item, *shadow_frame, JValue());
}
diff --git a/runtime/interpreter/interpreter_common.cc b/runtime/interpreter/interpreter_common.cc
index 3453abc..12d70c5 100644
--- a/runtime/interpreter/interpreter_common.cc
+++ b/runtime/interpreter/interpreter_common.cc
@@ -503,6 +503,7 @@
uint32_t vregC) ALWAYS_INLINE;
void ArtInterpreterToCompiledCodeBridge(Thread* self,
+ ArtMethod* caller,
const DexFile::CodeItem* code_item,
ShadowFrame* shadow_frame,
JValue* result)
@@ -530,6 +531,10 @@
uint16_t arg_offset = (code_item == nullptr)
? 0
: code_item->registers_size_ - code_item->ins_size_;
+ jit::Jit* jit = Runtime::Current()->GetJit();
+ if (jit != nullptr && caller != nullptr) {
+ jit->NotifyInterpreterToCompiledCodeTransition(self, caller);
+ }
method->Invoke(self, shadow_frame->GetVRegArgs(arg_offset),
(shadow_frame->NumberOfVRegs() - arg_offset) * sizeof(uint32_t),
result, method->GetInterfaceMethodIfProxy(sizeof(void*))->GetShorty());
@@ -726,7 +731,8 @@
target->GetEntryPointFromQuickCompiledCode())) {
ArtInterpreterToInterpreterBridge(self, code_item, new_shadow_frame, result);
} else {
- ArtInterpreterToCompiledCodeBridge(self, code_item, new_shadow_frame, result);
+ ArtInterpreterToCompiledCodeBridge(
+ self, shadow_frame.GetMethod(), code_item, new_shadow_frame, result);
}
} else {
UnstartedRuntime::Invoke(self, code_item, new_shadow_frame, result, first_dest_reg);
diff --git a/runtime/interpreter/interpreter_common.h b/runtime/interpreter/interpreter_common.h
index fb98175..e5b89e2 100644
--- a/runtime/interpreter/interpreter_common.h
+++ b/runtime/interpreter/interpreter_common.h
@@ -635,7 +635,7 @@
jit->InvokeVirtualOrInterface(
self, receiver, sf_method, shadow_frame.GetDexPC(), called_method);
}
- jit->AddSamples(self, sf_method, 1);
+ jit->AddSamples(self, sf_method, 1, /*with_backedges*/false);
}
// TODO: Remove the InvokeVirtualOrInterface instrumentation, as it was only used by the JIT.
if (type == kVirtual || type == kInterface) {
@@ -681,7 +681,7 @@
if (jit != nullptr) {
jit->InvokeVirtualOrInterface(
self, receiver, shadow_frame.GetMethod(), shadow_frame.GetDexPC(), called_method);
- jit->AddSamples(self, shadow_frame.GetMethod(), 1);
+ jit->AddSamples(self, shadow_frame.GetMethod(), 1, /*with_backedges*/false);
}
instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
// TODO: Remove the InvokeVirtualOrInterface instrumentation, as it was only used by the JIT.
@@ -1001,8 +1001,11 @@
return branch_offset <= 0;
}
-void ArtInterpreterToCompiledCodeBridge(Thread* self, const DexFile::CodeItem* code_item,
- ShadowFrame* shadow_frame, JValue* result);
+void ArtInterpreterToCompiledCodeBridge(Thread* self,
+ ArtMethod* caller,
+ const DexFile::CodeItem* code_item,
+ ShadowFrame* shadow_frame,
+ JValue* result);
// Explicitly instantiate all DoInvoke functions.
#define EXPLICIT_DO_INVOKE_TEMPLATE_DECL(_type, _is_range, _do_check) \
diff --git a/runtime/interpreter/interpreter_goto_table_impl.cc b/runtime/interpreter/interpreter_goto_table_impl.cc
index c95af6f..13cfb98 100644
--- a/runtime/interpreter/interpreter_goto_table_impl.cc
+++ b/runtime/interpreter/interpreter_goto_table_impl.cc
@@ -78,7 +78,7 @@
#define HOTNESS_UPDATE() \
do { \
if (jit != nullptr) { \
- jit->AddSamples(self, method, 1); \
+ jit->AddSamples(self, method, 1, /*with_backedges*/ true); \
} \
} while (false)
diff --git a/runtime/interpreter/interpreter_switch_impl.cc b/runtime/interpreter/interpreter_switch_impl.cc
index ca1d635..4323d4f 100644
--- a/runtime/interpreter/interpreter_switch_impl.cc
+++ b/runtime/interpreter/interpreter_switch_impl.cc
@@ -89,7 +89,7 @@
#define HOTNESS_UPDATE() \
do { \
if (jit != nullptr) { \
- jit->AddSamples(self, method, 1); \
+ jit->AddSamples(self, method, 1, /*with_backedges*/ true); \
} \
} while (false)
diff --git a/runtime/interpreter/mterp/mterp.cc b/runtime/interpreter/mterp/mterp.cc
index f800683..4b3c03e 100644
--- a/runtime/interpreter/mterp/mterp.cc
+++ b/runtime/interpreter/mterp/mterp.cc
@@ -689,7 +689,7 @@
jit::Jit* jit = Runtime::Current()->GetJit();
if (jit != nullptr) {
int16_t count = shadow_frame->GetCachedHotnessCountdown() - shadow_frame->GetHotnessCountdown();
- jit->AddSamples(self, method, count);
+ jit->AddSamples(self, method, count, /*with_backedges*/ true);
}
return MterpSetUpHotnessCountdown(method, shadow_frame);
}
@@ -702,7 +702,7 @@
uint32_t dex_pc = shadow_frame->GetDexPC();
jit::Jit* jit = Runtime::Current()->GetJit();
if ((jit != nullptr) && (offset <= 0)) {
- jit->AddSamples(self, method, 1);
+ jit->AddSamples(self, method, 1, /*with_backedges*/ true);
}
int16_t countdown_value = MterpSetUpHotnessCountdown(method, shadow_frame);
if (countdown_value == jit::kJitCheckForOSR) {
@@ -722,7 +722,7 @@
jit::Jit* jit = Runtime::Current()->GetJit();
if (offset <= 0) {
// Keep updating hotness in case a compilation request was dropped. Eventually it will retry.
- jit->AddSamples(self, method, 1);
+ jit->AddSamples(self, method, 1, /*with_backedges*/ true);
}
// Assumes caller has already determined that an OSR check is appropriate.
return jit::Jit::MaybeDoOnStackReplacement(self, method, dex_pc, offset, result);